How do I determine whether or not two lines intersect, and if they do, at what x,y point?
相关问题
- How to determine +/- sign when calculating diagona
- Union of many (more than two) polygons without hol
- Is there a way to rotate text around (or inside) a
- Filling rectangle with points pattern
- Unity Intersections Mask
相关文章
- Algorithm for partially filling a polygonal mesh
- Robust polygon normal calculation
- Algorithm for maximizing coverage of rectangular a
- SVG circle starting point
- How to calculate end points of perpendicular line
- Calculate the eccentricity of ellipses
- Draw a rectangle arround a polygon when given in c
- How to determine a diagonal is in or out of a conc
I read these algorithm from the book "multiple view geometry"
following text using
' as transpose sign
* as dot product
x as cross product, when using as operator
1. line definition
a point x_vec = (x, y)' lies on the line ax + by + c = 0
we denote L = (a, b, c)', the point as (x, y, 1)' as homogeneous coordinates
the line equation can be written as
(x, y, 1)(a, b, c)' = 0 or x' * L = 0
2. intersection of lines
we have two lines L1=(a1, b1, c1)', L2=(a2, b2, c2)'
assume x is a point, a vector, and x = L1 x L2 (L1 cross product L2).
be careful, x is always a 2D point, please read homogeneous coordinates if you are confused about (L1xL2) is a three elements vector, and x is a 2D coordinates.
according to triple product, we know that
L1 * ( L1 x L2 ) = 0, and L2 * (L1 x L2) = 0, because of L1,L2 co-plane
we substitute (L1xL2) with vector x, then we have L1*x=0, L2*x=0, which means x lie on both L1 and L2, x is the intersection point.
be careful, here x is homogeneous coordinates, if the last element of x is zero, it means L1 and L2 are parallel.
Just wanted to mention that a good explanation and explicit solution can be found in the Numeric Recipes series. I've got the 3rd edition and the answer is on page 1117, section 21.4. Another solution with a different nomenclature can be found in a paper by Marina Gavrilova Reliable Line Section Intersection Testing. Her solution is, to my mind, a little simpler.
My implementation is below:
Question C: How do you detect whether or not two line segments intersect?
I have searched for the same topic, and I wasn't happy with the answers. So I have written an article that explains very detailed how to check if two line segments intersect with a lot of images. There is complete (and tested) Java-code.
Here is the article, cropped to the most important parts:
The algorithm, that checks if line segment a intersects with line segment b, looks like this:
What are bounding boxes? Here are two bounding boxes of two line segments:
If both bounding boxes have an intersection, you move line segment a so that one point is at (0|0). Now you have a line through the origin defined by a. Now move line segment b the same way and check if the new points of line segment b are on different sides of line a. If this is the case, check it the other way around. If this is also the case, the line segments intersect. If not, they don't intersect.
Question A: Where do two line segments intersect?
You know that two line segments a and b intersect. If you don't know that, check it with the tools I gave you in "Question C".
Now you can go through some cases and get the solution with 7th grade math (see code and interactive example).
Question B: How do you detect whether or not two lines intersect?
Let's say your point
A = (x1, y1)
, pointB = (x2, y2)
,C = (x_3, y_3)
,D = (x_4, y_4)
. Your first line is defined by AB (with A != B), and your second one by CD (with C != D).Question D: Where do two lines intersect?
Check with Question B if they intersect at all.
The lines a and b are defined by two points for each line. You can basically apply the same logic was used in Question A.
Based on t3chb0t's answer:
Here's an improvement to Gavin's answer. marcp's solution is similar also, but neither postpone the division.
This actually turns out to be a practical application of Gareth Rees' answer as well, because the cross-product's equivalent in 2D is the perp-dot-product, which is what this code uses three of. Switching to 3D and using the cross-product, interpolating both s and t at the end, results in the two closest points between the lines in 3D. Anyway, the 2D solution:
Basically it postpones the division until the last moment, and moves most of the tests until before certain calculations are done, thereby adding early-outs. Finally, it also avoids the division by zero case which occurs when the lines are parallel.
You also might want to consider using an epsilon test rather than comparison against zero. Lines that are extremely close to parallel can produce results that are slightly off. This is not a bug, it is a limitation with floating point math.
Plenty of solutions are available above, but I think below solution is pretty simple and easy to understand.
Two segments Vector AB and Vector CD intersect if and only if
More specifically a and b are on opposite side of segment CD if and only if exactly one of the two triples a,c,d and b,c,d is in counterclockwise order.
Here CCW represent counterclockwise which returns true/false based on the orientation of the points.
Source : http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf Page 2