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
This is working well for me. Taken from here.
I tried some of these answers, but they didnt work for me (sorry guys); after some more net searching I found this.
With a little modification to his code I now have this function that will return the point of intersection or if no intersection is found it will return -1,-1.
The problem reduces to this question: Do two lines from A to B and from C to D intersect? Then you can ask it four times (between the line and each of the four sides of the rectangle).
Here's the vector math for doing it. I'm assuming the line from A to B is the line in question and the line from C to D is one of the rectangle lines. My notation is that
Ax
is the "x-coordinate of A" andCy
is the "y-coordinate of C." And "*
" means dot-product, so e.g.A*B = Ax*Bx + Ay*By
.This
h
number is the key. Ifh
is between0
and1
, the lines intersect, otherwise they don't. IfF*P
is zero, of course you cannot make the calculation, but in this case the lines are parallel and therefore only intersect in the obvious cases.The exact point of intersection is
C + F*h
.More Fun:
If
h
is exactly0
or1
the lines touch at an end-point. You can consider this an "intersection" or not as you see fit.Specifically,
h
is how much you have to multiply the length of the line in order to exactly touch the other line.Therefore, If
h<0
, it means the rectangle line is "behind" the given line (with "direction" being "from A to B"), and ifh>1
the rectangle line is "in front" of the given line.Derivation:
A and C are vectors that point to the start of the line; E and F are the vectors from the ends of A and C that form the line.
For any two non-parallel lines in the plane, there must be exactly one pair of scalar
g
andh
such that this equation holds:Why? Because two non-parallel lines must intersect, which means you can scale both lines by some amount each and touch each other.
(At first this looks like a single equation with two unknowns! But it isn't when you consider that this is a 2D vector equation, which means this is really a pair of equations in
x
andy
.)We have to eliminate one of these variables. An easy way is to make the
E
term zero. To do that, take the dot-product of both sides of the equation using a vector that will dot to zero with E. That vector I calledP
above, and I did the obvious transformation of E.You now have:
If each side of the rectangle is a line segment, and the user drawn portion is a line segment, then you need to just check the user drawn segment for intersection with the four side line segments. This should be a fairly simple exercise given the start and end points of each segment.
I have tried to implement the algorithm so elegantly described by Jason above; unfortunately while working though the mathematics in the debugging I found many cases for which it doesn't work.
For example consider the points A(10,10) B(20,20) C(10,1) D(1,10) gives h=.5 and yet it is clear by examination that these segments are no-where near each other.
Graphing this makes it clear that 0 < h < 1 criteria only indicates that the intercept point would lie on CD if it existed but tells one nothing of whether that point lies on AB. To ensure that there is a cross point you must do the symmetrical calculation for the variable g and the requirement for interception is: 0 < g < 1 AND 0 < h < 1
Finding the correct intersection of two line segments is a non-trivial task with lots of edge cases. Here's a well documented, working and tested solution in Java.
In essence, there are three things that can happen when finding the intersection of two line segments:
The segments do not intersect
There is a unique intersection point
The intersection is another segment
NOTE: In the code, I assume that a line segment (x1, y1), (x2, y2) with x1 = x2 and y1 = y2 is a valid line segment. Mathematically speaking, a line segment consists of distinct points, but I am allowing segments to be points in this implementation for completeness.
Code is taken from my github repo
Here is a simple usage example: