Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fillets at intersections #83

Open
vvoovv opened this issue Jan 12, 2024 · 8 comments
Open

Fillets at intersections #83

vvoovv opened this issue Jan 12, 2024 · 8 comments

Comments

@vvoovv
Copy link
Member

vvoovv commented Jan 12, 2024

Fillets make generating intersections more complicated.

There are a number of way to define a fillet (or an arc).

image

A possible way to define an arc is to give its start point, end point, the center of the arc and its radius. Generation of in-between points of an arc can be delegated to Geometry Nodes.

@vvoovv
Copy link
Member Author

vvoovv commented Jan 12, 2024

A workflow is proposed below to process and generate intersections with fillets.

Let’s consider an example on the image below.

image

The roadway to the left is composed of the sequence SectionCrosswalkSectionIntersection.

A PML style of the intersection is queried for the fillet radius. Based on the fillet radius the parameters of the fillet are calculated, namely, the start point, the end point, the center of the arc and its radius.

Class instances representing the areas marked with the blue color on the image above are created. This area type can be called an inverted fillet.

Sections are not affected by fillets. But Crosswalks are affected by them. Extensions of a crosswalk must be calculated, namely areas marked with the letter C. In particular, intersections (green circles) of the crosswalk border with the original fillet must be calculated. A crosswalk gets a new border partially formed by an arc.

Finally, areas marked with the letter C are subtracted from the inverted fillets (marked with the blue color) to form areas marked with the letter F. The latter areas also contain an arc in many cases.

@polarkernel
Copy link
Collaborator

Doesn't fillet have a double-L? In my language, filet means a piece of meat. I don't know if fillet is related to fill, but as far as I know, it has two Ls.

Ways do not always meet perpendicularly at an intersection. Just for documentation, I want to describe how to compute fillets to fit between two ways:

The gray rectangles symbolize two adjacent ways, that leave an intersection. P is the point where their boundaries intersect. The directions of the ways are given by their unit vectors uV1 and uV2, which can be taken from the centerline directions of the ways. The cosine of the angle α can be computed using the dot product to

cos(a) = uV1[0] * uV2[0] + uV1[1] * uV2[1]

Using a trigonometric equation, the tangent of half the angle α, tan(α/2), is given by

tan(a/2) = sqrt( (1 - cos(a) )/ (1 + cos(a) )

Given the radius R of the fillet arc, the length L to the tangent points tP1 and tP2 becomes

L = R/tan(a/2)

and the tangent points themselves are

tP1 = P + uV1 * L
tP2 = P + uV2 * L

Finally, the origin O of the arc is, using the perpendicular unit vector perpV = (uV2[1],-uV2[0])

O = tP2 + R * perpV

@vvoovv vvoovv changed the title Filets at intersections Fillets at intersections Jan 12, 2024
@vvoovv
Copy link
Member Author

vvoovv commented Jan 12, 2024

Doesn't fillet have a double-L? In my language, filet means a piece of meat. I don't know if fillet is related to fill, but as far as I know, it has two Ls.

Sorry, there is certainly a double L there: fiLLet.

@vvoovv
Copy link
Member Author

vvoovv commented Jan 15, 2024

Calculation of the intersection of a line and an arc (circle)

image

The line is marked with the blue color on the image above. It is defined by the initial point P and the unit vector e.

PX = P + x * e
XO = PO - PX = PO - P - x * e

The dot product of the above expression:

XO^2 = R^2 = PO^2 - 2 * PO * P + P^2 - 2 * x * (PO - P) * e + x^2

Moving everything to one side:

x^2 - 2 * x * (PO - P) * e + PO^2 - 2 * PO * P + P^2 - R^2 = 0

It's a quadratic equation. Its discriminant:

d = 4 * [ (PO - P) * e ]^2 - 4 * PO^2 + 8 * PO * P - 4 * P^2 + 4 * R^2

If d < 0, the line doesn't intersect the circle. If d > 0 the line intersects the circle twice.

We are interested in the intersection point that is the closest to the point P. Then

x = -0.5 * ( b + sqrt(d) )

The remaining step is to check that the line intersects the arc. Let R1 and R2 be the vectors from the center of the arc (circle) to its start and end points. The cross products of R1 and OX and R2 and OX must have an opposite sign. The dot products R1and OX andR2andOX` must be positive.

@vvoovv
Copy link
Member Author

vvoovv commented Sep 29, 2024

Just for documentation, I want to describe how to compute fillets to fit between two ways:

What if the length of either or both of the last segments of the carriageways on image is less than the distances between the points P and tP1 or P and tP2 respectively?

@polarkernel
Copy link
Collaborator

What if the length of either or both of the last segments of the carriageways on image is less than the distances between the points P and tP1 or P and tP2 respectively?

It's been a long time! The last time I implemented fillets was in September 2022. I didn't really have a solution for this issue. If one or both legs of the angle were too short, the radius was iteratively reduced by 10% until a fit was possible. Like this, often the reduction was acceptable.

I remember, before that, I tried to follow the roads segment by segment on both sides, extending them and hoping that eventually they would fit. But the results were weird. Additionally, even then, the streets were often still too short.

@vvoovv
Copy link
Member Author

vvoovv commented Sep 29, 2024

If one or both legs of the angle were too short, the radius was iteratively reduced by 10% until a fit was possible.

I haven't checked it yet by myself, but doesn't a precise solution for a curve radius exist, so the curve fits to the length of the shortest leg length?

@polarkernel
Copy link
Collaborator

polarkernel commented Sep 30, 2024

I haven't checked it yet by myself, but doesn't a precise solution for a curve radius exist, so the curve fits to the length of the shortest leg length?

I didn't think about that back then, but yes, it does exist. Given tan(a/2), start with the third equation above:

L = R/tan(a/2)

If we take L as the shortest leg length and solve the equation for R, we get

R = L*tan(a/2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants