Algorithm 闭合多边形链与直线的交点

Algorithm 闭合多边形链与直线的交点,algorithm,geometry,Algorithm,Geometry,我需要找到找到闭合多边形链和直线的2个交点的算法。 我的多边形链被定义为一个设定点坐标(x,y),我还有直线方程 准确地说,请看下图。我的输入是直线方程和P1…Pn。我想找到点X1和X2的坐标 给定该直线的方程式为a*x+b*y+c=0,您可以找出该直线的哪一侧是每个点,只需将该点的x,y坐标插入该表达式中即可: S_k = a*x_k + b*y_k + c 对于直线上的点,结果S_k为0(符合直线方程)。对于线一侧的点,结果将大于0,对于线另一侧的点,结果将小于0。按顺序对每个点执行此操作

我需要找到找到闭合多边形链和直线的2个交点的算法。 我的多边形链被定义为一个设定点坐标(x,y),我还有直线方程

准确地说,请看下图。我的输入是直线方程和
P1…Pn
。我想找到点X1和X2的坐标


给定该直线的方程式为
a*x+b*y+c=0
,您可以找出该直线的哪一侧是每个点,只需将该点的x,y坐标插入该表达式中即可:

S_k = a*x_k + b*y_k + c

对于直线上的点,结果
S_k
为0(符合直线方程)。对于线一侧的点,结果将大于0,对于线另一侧的点,结果将小于0。按顺序对每个点执行此操作,直到符号切换:
S_k*S_{k-1}<0
。这条线在
P_k
P_{k-1}
之间交叉

最初的问题是:给定a中的一组点和一条直线的方程,找到所有交点

我们必须谨慎地设计一种算法来解决这个问题,因为我们不假设: *直线的方程式具有实斜率和非零斜率,或 *多边形链是简单的或自相交的,无论它是绑定到凹多边形还是凸多边形

例如,考虑直线的方程式为
x=a
,这意味着它的斜率为∞, i、 e.与y轴平行:

这里,我们不能通过在直线方程中插入PiPi+1来测试交点(它们给出了相同的值!)

此外,该示例还说明了为什么无法通过任一直线是否垂直来求解交点Xi

提供解决所有情况的简单算法将涉及通过多边形边界框剪裁直线,并解决生成的线段与多边形每条边之间的交点

算法:

V为二维欧几里德空间(R2)中闭合多边形链的n点集,P1,…,Pn,且L为直线,也位于R2中,由以下形式的线性方程描述:

其中a、b和c是已知的实标量,a和b不是都为零

  • 计算P1,…,Pn的边界框。注意:轴对齐的最小边界框是最简单的,可以轻松计算:

    设X=V和V中点的X分量集 Y=V中点的Y分量集

    定义轴对齐最小边界框顶点的闭合多边形链为: (最小(X),最小(Y)), (最大(X),最小(Y)), (最大值(X),最大值(Y)), (最小(X),最大(Y)), (最小(X),最小(Y))

  • 通过刚才计算的边界框剪裁线L,以生成线段L',该线段由向量对uv和标量t描述:

  • 要查找uv,我们必须计算直线与边界框每条边相交的位置:

    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)
    
    当线段处于参数化形式时,查找线段之间的交点很容易。基本上,两条线段相互正交投影,并检查特殊情况

    提出了一种求一对线段交点的算法


    为了获得更深入的解释,我们将详细介绍线段相交算法。

    您不能在此处直接编写make,这与使用$$表示TeX不同。但是,您可以使用backticks`编写使用固定宽度字体的简单公式,例如
    S_k*S_{k-1}<0
    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.