当前位置:  开发笔记 > 编程语言 > 正文

如何测试线段是否与2D中的轴对齐矩形相交?

如何解决《如何测试线段是否与2D中的轴对齐矩形相交?》经验,为你挑选了5个好方法。

如何测试线段是否与2D中的轴对齐矩形相交?该段的两端定义为:p1,p2.矩形定义为左上角和右下角.



1> 小智..:

原始海报想要检测线段和多边形之间的交叉点.如果有交叉点,则无需定位交叉点.如果这就是你的意思,那么你可以做的工作少于Liang-Barsky或Cohen-Sutherland:

设分段端点为p1 =(x1 y1),p2 =(x2 y2).
让矩形的角为(xBL yBL)和(xTR yTR).

那么你所要做的就是

A.检查矩形的所有四个角是否都在线的同一侧.通过p1和p2的线的隐式方程是:

F(xy)=(y2-y1)*x +(x1-x2)*y +(x2*y1-x1*y2)

如果F(xy)= 0,则(xy)在该行上.
如果F(xy)> 0,则(xy)在该线的"上方".
如果F(xy)<0,则(xy)在该线的"下方".

将所有四个角替换为F(xy).如果它们都是负数或全部为正数,则没有交集.如果有些是肯定的而有些是否定的,请转到步骤B.

B.将端点投影到x轴上,并检查线段的阴影是否与多边形的阴影相交.在y轴上重复:

如果(x1> xTR和x2> xTR),则没有交点(行是矩形的右边).
如果(x1 如果(y1> yTR和y2> yTR),则没有交点(线在矩形上方).
如果(y1 否则,有一个十字路口.Cohen-Sutherland或您问题的其他答案中提到的任何代码.

当然,你可以先做B,然后做A.

阿莱霍



2> metamal..:

写了非常简单和有效的解决方案:

      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;
  }


这非常简单,效果很好!我做了一个javascript测试:http://jsfiddle.net/77eej/2/

3> ryan_s..:

由于矩形是对齐的,所以Liang-Barsky可能是一个很好的解决方案.如果速度很重要,它比Cohen-Sutherland快.

Siggraph解释
另一个很好的描述
当然,维基百科



4> 小智..:

你还可以在段之外创建一个矩形,并测试另一个矩形是否与它发生碰撞,因为它只是一系列的比较.来自pygame来源:

def _rect_collide(a, b):
    return a.x + a.w > b.x and b.x + b.w > a.x and \
           a.y + a.h > b.y and b.y + b.h > a.y


这太简单而且过于热切.它将收集误差,其中线的起点在x但不是y重叠,并且线的末端在y中重叠,但不在x中重叠(反之亦然).

5> Kevin Conner..:

使用Cohen-Sutherland算法.

它用于剪裁,但可以稍微调整一下这项任务.它将2D空间划分为井字板,矩形为"中心正方形".
然后检查你的线的两个点中的九个区域中的哪一个.

如果两个点都是左,右,上或下,那么你就会轻易拒绝.

如果任何一点在里面,你就可以接受了.

在极少数情况下,您可以根据它们所在的区域,与矩形中可能相交的任何一侧进行数学交叉.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有