问题
I have a square in 2d space (width = height). The square is currently defined by two points: BottomLeft(X1,Y1) and TopRight(X2,Y2).
The square is axis-aligned, so finding the other two corners is as easy as (X1, Y2) and (X2, Y1).
I also have two points - one is always inside the square, and the other is definitely outside. They aren't necessarily at the centre of the square - they can be wherever. I know their coordinates too.
What I need is to find the intersection point between the line segment defined by these two points, and the side of the square. I also want to know which side of the square I intersected. What gives me trouble are cases where the line goes diagonally, and close to the corner of the square - so for example it can either intersect top or the side line.
The brute-force method is to try and calculate the intersections for each side of the square and check if it exists. It can be optimized by calculating where in relation to the square the second point lies, and discarding two lines (for example if both X and Y coordinates increase, there's no need to check bottom and left sides of the square).
I'm wondering if there's a better/faster solution to my problem? I'll be writing in Java
回答1:
Let inside point is (x0, y0)
, outside point is (ox, oy)
Represent line in parametric form
vx = ox - x0
vy = oy - y0
//equations:
x = x0 + vx * t
y = y0 + vy * t
Now find potential border positions depending on direction:
if vx > 0 then
ex = x2
else
ex = x1
if vy > 0 then
ey = y2
else
ey = y1
Check extra cases of horizontal/vertical line direction:
if vx = 0 then
return cx = x0, cy = ey
if vy = 0 then
return cx = ex, cy = y0
In general case find parameters of intersections with horizontal and vertical edge lines
tx = (ex - x0) / vx
ty = (ey - y0) / vy
And get intersection for smaller parameter value
if tx <= ty then //meet vertical edge first
return cx = ex, cy = y0 + tx * vy
else
return cx = x0 + ty * vx, cy = ey
回答2:
Efficient solution:
I assume that you know which point is inside the square (can also be a rectangle).
Subtract the coordinates of this point from all other points (the second endpoint and the four corners). Consider the subdivision of the plane in nine areas formed by extending the sides of the square. It takes four sign tests to know in which of the eight outside areas the other point lies.
Then if that point lies in a "side" area, you implicitly know which side is crossed. If the point lies in a "corner" area, you have to decide between two sides, and this is done by checking of which side of the line segment the corner lies. This takes the computation of the signed area of a triangle (two multiplies and one subtract).
When you know which side is crossed, it is an easy matter to find the intersection point, by using a proportion. This takes a single division.
Finally, you translate back to the original position of the inner point. The total cost is
four subtracts,
four sign tests,
in the case of the corner areas, two multiplies and one subtract,
one division,
two additions
plus a little of glue logic.
This is not guaranteed to be an absolute minimum, but it must be close to.
来源:https://stackoverflow.com/questions/58055629/intersection-between-a-line-and-square