简体   繁体   English

直线与正方形的交点

[英]intersection between a line and square

I have a square in 2d space (width = height).我在二维空间中有一个正方形(宽度 = 高度)。 The square is currently defined by two points: BottomLeft(X1,Y1) and TopRight(X2,Y2).该正方形当前由两个点定义:BottomLeft(X1,Y1) 和 TopRight(X2,Y2)。

The square is axis-aligned, so finding the other two corners is as easy as (X1, Y2) and (X2, Y1).正方形是轴对齐的,因此找到其他两个角就像 (X1, Y2) 和 (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).可以通过计算第二个点相对于正方形的位置并丢弃两条线来优化它(例如,如果 X 和 Y 坐标都增加,则无需检查正方形的底部和左侧)。

I'm wondering if there's a better/faster solution to my problem?我想知道是否有更好/更快的解决方案来解决我的问题? I'll be writing in Java我会写在 Java

Let inside point is (x0, y0) , outside point is (ox, oy)设内点为(x0, y0) ,外点为(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

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.最后,你翻译回原来的 position 的内点。 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.这不能保证是绝对最小值,但必须接近。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM