如何在2D中测试线段是否与轴对齐的矩形相交?
如何在2D中测试线段是否与轴对齐的矩形相交?段的两端定义为:p1,p2. 矩形由左上角和右下角定义。
解决方案
使用Cohen-Sutherland算法。
它用于剪辑,但可以略微调整此任务。它将2D空间划分为一个井字游戏板,矩形作为"中心正方形"。
然后它会检查线的两个点分别在九个区域中的哪个区域。
- 如果两个点都在左,右,上或者下,我们将微不足道。
- 如果其中任一点在里面,我们都会微不足道地接受。
- 在极少数情况下,我们可以根据矩形所在的区域进行数学运算,以使其与矩形的任意可能相交。
快速的Google搜索弹出带有C ++代码的页面,用于测试路口。
基本上,它测试线与每个边界或者矩形之间的交点。
矩形和直线相交代码
由于矩形已对齐,因此Liang-Barsky可能是一个很好的解决方案。如果此处的速度显着,则它比科恩-萨瑟兰(Cohen-Sutherland)快。
信号图说明
另一个很好的描述
当然,维基百科
我做了一点餐巾纸溶液。
接下来找到m和c,因此等式y = mx + c
y = (Point2.Y - Point1.Y) / (Point2.X - Point1.X)
替换P1坐标以查找c
现在,对于矩形顶点,将X值放入线方程中,获取Y值,然后查看Y值是否位于下面所示的矩形边界内
(我们可以找到矩形的常量值X1,X2,Y1,Y2,这样)
X1 <= x <= X2 & Y1 <= y <= Y2
如果Y值满足上述条件并且位于(Point1.Y,Point2.Y)之间,则我们有一个交点。
如果该顶点无法切入,请尝试每个顶点。
编写了非常简单有效的解决方案:
bool SegmentIntersectRectangle(double a_rectangleMinX, double a_rectangleMinY, double a_rectangleMaxX, double a_rectangleMaxY, double a_p1x, double a_p1y, double a_p2x, double a_p2y) { // Find min and max X for the segment double minX = a_p1x; double maxX = a_p2x; if(a_p1x > a_p2x) { minX = a_p2x; maxX = a_p1x; } // Find the intersection of the segment's and rectangle's x-projections if(maxX > a_rectangleMaxX) { maxX = a_rectangleMaxX; } if(minX < a_rectangleMinX) { minX = a_rectangleMinX; } if(minX > maxX) // If their projections do not intersect return false { return false; } // Find corresponding min and max Y for min and max X we found before double minY = a_p1y; double maxY = a_p2y; double dx = a_p2x - a_p1x; if(Math::Abs(dx) > 0.0000001) { double a = (a_p2y - a_p1y) / dx; double b = a_p1y - a * a_p1x; minY = a * minX + b; maxY = a * maxX + b; } if(minY > maxY) { double tmp = maxY; maxY = minY; minY = tmp; } // Find the intersection of the segment's and rectangle's y-projections if(maxY > a_rectangleMaxY) { maxY = a_rectangleMaxY; } if(minY < a_rectangleMinY) { minY = a_rectangleMinY; } if(minY > maxY) // If Y-projections do not intersect return false { return false; } return true; }
原始海报想要检测线段和多边形之间的交点。如果有交叉点,则无需定位。如果这就是意思,那么我们可以做的工作比Liang-Barsky或者Cohen-Sutherland少:
令段端点为p1 =(x1 y1)和p2 =(x2 y2)。
令矩形的角为(xBL yBL)和(xTR yTR)。
那你要做的就是
A.检查矩形的所有四个角是否在直线的同一侧。
通过p1和p2的直线的隐式方程为:
F(x y)=(y2-y1)* x +(x1-x2)* y +(x2 * y1-x1 * y2)
如果F(x y)= 0,则(x y)为ON。
如果F(x y)> 0,则(x y)在该行上方。
如果F(x y)<0,则(x y)在该行"下方"。
将所有四个角代入F(x y)。如果它们全部为负或者全部为正,则没有交集。如果有些是肯定的而有些是消极的,请转到步骤B。
B.将端点投影到x轴上,并检查线段的阴影是否与多边形的阴影相交。在y轴上重复:
如果(x1> xTR和x2> xTR),则没有交点(直线在矩形的右边)。
如果(x1 <xBL并且x2 <xBL),则没有交点(直线在矩形的左侧)。
如果(y1> yTR且y2> yTR),则无交集(直线在矩形上方)。
如果(y1 <yBL并且y2 <yBL),则没有交点(直线在矩形下方)。
否则,有一个交叉点。回答科恩·萨瑟兰(Cohen-Sutherland)或者其他答案中提到的任何代码。
我们当然可以先做B,然后再做A。
阿列霍