intersection between a line and square

让人想犯罪 __ 提交于 2020-01-16 14:52:42

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!