我试图找到一个矩形是否与凹多边形相交。这个算法能实现吗?

时间:2010-08-11 22:05:54

标签: algorithm pseudocode

我试图找到一个矩形是否与凹多边形相交。我找到了这个算法:

double determinant(Vector2D vec1, Vector2D vec2){
    return vec1.x*vec2.y-vec1.y*vec2.x;
}

//one edge is a-b, the other is c-d
Vector2D edgeIntersection(Vector2D a, Vector2D b, Vector2D c, Vector2D d){
    double det=determinant(b-a,c-d);
    double t=determinant(c-a,c-d)/det;
    double u=determinant(b-a,c-a)/det;
    if ((t<0)||(u<0)||(t>1)||(u>1))return NO_INTERSECTION;
    return a*(1-t)+t*b;
}

如果我执行4次(从上到下,从上到下,从上到下,从下到右)*(我的多边形的所有边缘)这将有效且准确地告诉我矩形是否具有部分或里面的所有凹多边形?如果不是会遗漏什么?

由于

3 个答案:

答案 0 :(得分:13)

代码试图找到两个段的交叉点 - AB和CD。

根据您解释这些操作的方式,有许多不同的方法可以解释它是如何做到的。

假设A点有坐标(xa,ya),B - (xb,yb)等等。我们说

dxAB = xb - xa
dyAB = yb - ya
dxCD = xd - xc
dyCD = yd - yc

以下两个线性方程组

| dxAB dxCD |   | t |   | xc-xa |
|           | * |   | = |       |
| dyAB dyCD |   | u |   | yc-ya |

如果为tu求解,将为您提供AB线(值t)和线CD(值u)上交叉点的比例位置)。如果该点属于相应的段,则这些值将位于[0, 1]的范围内;如果该点位于该段之外(在包含该段的行上),则这些值将位于该范围之外。

为了解决这个线性方程组,我们可以使用众所周知的Cramer's rule。为此我们需要

的决定因素
| dxAB dxCD |
|           |
| dyAB dyCD |

与您的代码完全相同determinant(b - a, c - d)。 (实际上,我在这里有determinant(b - a, d - c),但对于这个解释的目的并不重要。你发布的代码由于某种原因交换C和D,见下面的P.S.注释。

我们还需要

的决定因素
| xc-xa dxCD |
|            |
| yc-ya dyCD |

与您的代码完全相同determinant(c-a,c-d)

的决定因素
| dxAB xc-xa |
|            |
| dyAB yc-ya |

正是determinant(b-a,c-a)

根据Cramer的规则划分这些决定因素将为我们提供tu的值,这正是您发布的代码中所做的。

然后代码会继续测试tu的值,以检查这些段是否实际相交,即tu是否属于{{1} }} 范围。如果他们这样做,它会通过评估[0, 1]来计算实际交叉点(相当于它可以评估a*t+b*(1-t))。 (再次参见下面的P.S.注释)。

P.S。在原始代码中,点D和C在代码执行c*u+d*(1-u)的意义上是“交换”的,我在解释中c - d。但这对算法的一般概念没有任何影响,只要一个人注意标志。

此C和D点的交换也是在评估交叉点时使用d - c表达式的原因。通常,正如在我的解释中,人们希望在那里看到像a*(1-t)+t*b这样的东西。 (我对此有疑问。我希望即使在您的版本中也会看到a*t+b*(1-t)。可能是个错误。)

P.P.S。作者如果代码忘记检查a*t+b*(1-t)(或非常接近0),则会在段并行时发生。

答案 1 :(得分:2)

我认为以下内容应该有效:

(1) for each e1 in rectangle_edges, e2 in polygon_edges
    (1.1) if edgeIntersection(e1,e2) != NO_INTERSECTION
        (1.1.1) return true
(2) if (max_polygon_x < max_rectangle_x) and (min_polygon_x > min_rectangle_x) and (max_polygon_y < max_rectangle_y) and (min_polygon_y > min_rectangle_y)
    (2.1) return true
(2) return false

编辑:添加检查多边形是否在矩形内。

答案 2 :(得分:0)

据我所知,在快速浏览之后,它会尝试确定两个线段是否相交,如果它们相交,那么交点的坐标是什么。

不,确定你的矩形和多边形是否相交是不够的,因为你仍然会错过多边形完全位于矩形内部或相反的情况。