我需要找到找到闭合多边形链和线的2个交点的算法。 我的多边形链被定义为设定点坐标(x,y),我也有线的方程。
准确地说,请看下面的图片。我的输入是行的等式P1...Pn
。我想找到点X1和X2的坐标。
答案 0 :(得分:1)
如果该行的等式为a*x+b*y+c=0
,您可以找到该行的哪一侧,只需将点P_k
的x,y坐标插入该表达式:< / p>
S_k = a*x_k + b*y_k + c
对于线上的点,结果S_k
为0(它遵循线方程)。对于线的一侧上的点,结果将是> 0,对于另一侧的点,结果将是&lt; 0.对每个点按顺序执行此操作,直到符号切换为S_k * S_{k-1} < 0
。该行跨越P_k
和P_{k-1}
。
答案 1 :(得分:0)
最初的问题是:给定closed polygonal chain中的一组点和一条线的等式,找到所有的交点。
我们必须注意设计一个算法来解决这个问题,因为我们不会对是否: *该行的等式具有实和非零斜率,或者 *多边形链是简单或自相交,以及它是否绑定到凹面或凸面多边形。
例如,考虑special case,其中线的等式为x = a
,意味着它的斜率为∞,即它与y轴平行:
在这里,我们不能通过插入 P i 和 P i + 1 测试的交叉点> 进入线方程(它们给出相同的值!)。
此外,这个例子还说明了为什么我们不能解决的交叉点, X i ,{{3}如果任一行是垂直的。
提供解决所有案例的解决方案的天真算法将涉及通过多边形的边界框剪切线条并解决生成的线段与多边形的每个边缘之间的交点。
<强>算法:强>
让 V 成为闭合多边形链的一组 n 点, P 1 ,... 。, P n ,在二维欧氏空间( R 2 )和 L 是一条线,也在 R 2 中,由形式的线性方程描述:
其中 a , b 和 c 是已知的真实标量, a 和 b < / em>不是都是零。
计算 P 1 ,..., P n 的边界框。 注意: 轴对齐的最小边界框是最简单的,可以轻松计算:
设X = V和中点的x分量的集合 Y = V中点的y分量集。
定义轴对齐最小边界框顶点的闭合多边形链是: (min(X),min(Y)), (max(X),min(Y)), (max(X),max(Y)), (min(X),max(Y)), (min(X),min(Y))
通过我们刚刚计算出的边界框剪切 L 线以生成线段 L&#39; ,由一对矢量描述你和 v 和标量 t :
要查找 u 和 v ,我们必须计算线与边界框的每条边相交的位置:
Let B = the closed polygonal chain defining the vertices of the axis-aligned rectangular bounding box we just calculated, with B(i) = the i-th point in the chain.
For i = 1 to 4:
Let j = i + 1. Then:
xi = the x component of Bi
yi = the y component of Bi
xj = the x component of Bj
yj = the y component of Bj
If xi == xj: # The edge is vertical
Let xk = xi.
If b != 0:
yk = (c - a * xk) / b # Calculate the y component of the line at xk
If (yi <= yk AND yk <= yj) OR (yj <= yk AND yk <= yi):
The line intersects at (xk, yk)!
Else: # b == 0, implying a vertical line
If xk == c / a:
The vertical line is at xk, so define two intersecting points as the ends of the line segment:
(xk, yi) and (xk, yj)
Else If yi == yj: # the edge is horizontal
Let yk = yi.
If a != 0:
xk = (c - b * yk) / a # Calculate the x component of the line at yk
If (xi <= xk AND xk <= xj) OR (xj <= xk AND xk <= xi):
The line intersects at (xk, yk)!
Else: # a == 0, implying a horizontal line
If yk == c / b:
The horizontal line is at yk, so define two intersecting points as the ends of the line segment:
(xi, yk) and (xj, yk)
注意:这是一个简单的算法,用于检测简单的轴对齐的最小边界框的交叉点,如步骤1中所述。对于其他四边形,更多需要复杂的推广来解释xi!= xj AND yi!= yj的情况。
运行此循环后,线与边界框之间将有0,1或2个相交点。
如果找到 2 交叉点,则计算 u 和 v 如下所示:
将两个交叉点定义为(xa,ya)和(xb,yb)。然后:
u =(xa,ya)和 v =(xb - xa,yb - ya)
最后,我们将线条剪切到线段,结尾为 u , u + v 。
将V(k)
定义为 V 中的第k个点, P k 。
For i = 1 to n - 1:
Let p = V(i) and
q = V(i + 1) - V(i),
such that p and q are the end points of the edge/line segment between vertices i and i + 1.
With u and v from the last step, find any intersecting points between the line segments:
u + t * v, and
p + s * q,
where s is a scalar and 0 <= s <= 1.
当它们处于参数形式时,很容易找到线段之间的交点。基本上,两个线段正交投射到彼此,并检查特殊情况。
用于查找一对线段之间的交叉点的算法是rearranging the linear equations。
有关更深入的解释,described here on SO previously详细介绍了线段交叉算法。