C 多边形相交

C 多边形相交,c,algorithm,polygons,C,Algorithm,Polygons,给出了两个多边形。如何确定一个多边形是在另一个多边形的内部、外部还是与另一个多边形相交? 多边形可以是凹的也可以是凸的。这里有一个简单的算法,可以知道给定点是在给定多边形的内部还是外部: bool isInside(point a, polygon B) { double angle = 0; for(int i = 0; i < B.nbVertices(); i++) { angle += angle(B[i],a,B[i+1]); }

给出了两个多边形。如何确定一个多边形是在另一个多边形的内部、外部还是与另一个多边形相交?
多边形可以是凹的也可以是凸的。

这里有一个简单的算法,可以知道给定点是在给定多边形的内部还是外部:

bool isInside(point a, polygon B)
{
    double angle = 0;
    for(int i = 0; i < B.nbVertices(); i++)
    {
        angle += angle(B[i],a,B[i+1]);
    }
    return (abs(angle) > pi);
}
bool-isInside(点a,多边形B)
{
双角度=0;
对于(int i=0;ipi);
}
  • 如果a的直线段与B的直线段相交,则两个多边形彼此相交
  • 否则,如果多边形A的所有点都在多边形B内,则A在B内
  • 否则,如果多边形B的所有点都在多边形A内,则B在A内
  • 否则,如果多边形A的所有点都在多边形B之外,则A在B之外
  • 否则,两个多边形将相交

您希望对凸多边形使用分离轴定理。 基本上,对于每个多边形的每个面,将每个多边形投影到该面的法线上,然后查看这些投影是否相交

您可以执行各种技巧来减少必须执行的这些计算的数量-例如,您可以围绕对象绘制一个矩形,并假设如果两个对象的矩形不相交,则它们本身也不相交。(这更容易,因为检查这些框的交点的计算成本更低,而且通常非常直观。)


凹多边形更难。我认为你可以把多边形分解成一组凸多边形,并试图检查每个相交的组合,但我认为在这方面我不太擅长尝试。

< P>有一个简单的方法来检查点是否位于多边形中。根据这一点,它被称为光线投射算法

该算法的基本思想是从要测试的点向任意方向投射光线,并计算它与多边形相交的边数。如果该数字为偶数,则该点位于多边形外部,否则,如果该数字为奇数,则该点位于多边形内部

这个算法有很多问题我不想深入探讨(我在前面链接的维基百科文章中讨论过),但这就是我称这个算法为easyish的原因。但为了让您了解情况,您必须处理涉及光线相交顶点、光线平行运行并与边相交以及点靠近边时的数值稳定性问题的角点情况


然后,您可以按照Thomas在回答中描述的方法使用此方法来测试两个多边形是否相交。这将为您提供一个
O(NM)
算法,其中两个多边形分别具有
N
M
顶点。

通常,类似的问题可以通过扫描线算法轻松解决。然而,使用扫描线方法的主要目的和好处是,当输入由两组相对较大的多边形组成时,它可以有效地解决问题。一旦实现了扫描线解决方案,如果需要,也可以将其有效地应用于一对多边形。也许你应该考虑朝着这个方向前进,以防将来需要解决一个巨大的问题。
但是,如果您确定需要两个且仅两个多边形的解决方案,则可以通过顺序点对多边形和分段对多边形测试来解决此问题。

可用于解决此问题。另请参见。最简单但不是最优化的方法:将多边形a拆分为不相交且覆盖所有多边形的三角形。并检查多边形B和A中每个三角形之间的交点。也可以尝试按三角形分割,并检查彼此之间的集合。我不确定您的
isInside
方法是否适用于凹多边形;我想S形可能会把它弄坏。即使它能正常工作,如果你只考虑角点(你需要考虑边上的所有点),那么检测2个多边形是否相交的算法是不起作用的,那么考虑2个矩形来形成一个十字,看看为什么。实际上,我不认为<代码>内/ <代码>对三角形也是有效的。(即使你修正了关于双倍和0的相等性的精确问题)。考虑第一点上的一个点和一个完全包含在第一象限中的三角形。谢谢你的评论,实际上我的<代码>内部/<代码>函数是完全错误的,好的一个使用<代码>角度(b [i],a,b[i+1])< /C> >代替<代码> ARG(b[i] -a)测试等于0是不是问题,因为结果总是2个π的倍数。你也对这两个矩形的正确性,我将用这个更新我的答案。@ ToMase:测试相等到0是一个问题,因为浮点错误。不,因为我刚才所说,结果是2 *PI的倍数,所以你可以考虑如果< COD。e> abs(角度)在这里找到一些扫描线算法: