Algorithm 如何检查线段是否与矩形相交?

Algorithm 如何检查线段是否与矩形相交?,algorithm,language-agnostic,geometry,computational-geometry,Algorithm,Language Agnostic,Geometry,Computational Geometry,如果有两个点(x1,y1)和(x2,y2),分别表示矩形的两个相对角,以及另外两个点(x3,y3)和(x4,y4),分别表示线段的两个端点,如何检查线段是否与矩形相交 (线段只是包含在给定端点之间的线段。它不是由这两点定义的无限长直线。)一个非常简单的选项是检查线段是否与构成方框角的四条线段中的任何一条相交。在计算上,检查两条线段是否相交是非常有效的,所以我希望这可以运行得非常快 希望这有帮助 获取所有4个顶点(矩形的角点)与线段方向向量的点积。如果所有4个具有相同符号的值,则所有顶点位于直线的

如果有两个点(x1,y1)和(x2,y2),分别表示矩形的两个相对角,以及另外两个点(x3,y3)和(x4,y4),分别表示线段的两个端点,如何检查线段是否与矩形相交


(线段只是包含在给定端点之间的线段。它不是由这两点定义的无限长直线。)

一个非常简单的选项是检查线段是否与构成方框角的四条线段中的任何一条相交。在计算上,检查两条线段是否相交是非常有效的,所以我希望这可以运行得非常快


希望这有帮助

获取所有4个顶点(矩形的角点)与线段方向向量的点积。如果所有4个具有相同符号的值,则所有顶点位于直线的同一侧(不是直线段,而是无限直线),因此直线不与矩形相交。该方法仅适用于二维相交检测。这可以用于快速过滤其中的大部分(仅使用乘法和加法)。您必须进一步检查线段而不是直线。

要了解如何推导测试线段是否与矩形相交的公式,请记住矩形的属性

将线段表示为单位向量以及线段起点与原点之间的距离。下面是一些C代码,可以通过变量
a#ptStart
a#ptEnd
计算,使用:

您还需要计算线段的垂直向量及其与原点的距离。将单位矢量旋转90°是正确的

假设矩形的四个角位于称为
vector1
vector2
vector3
vector4
vector4
变量中,计算线段与目标边界矩形的所有四个角之间的距离:

double dPerpLineDist1 = Vector.Multiply(vecPerpLine, vecRect1) - dDistPerpLine;
double dPerpLineDist2 = Vector.Multiply(vecPerpLine, vecRect2) - dDistPerpLine;
double dPerpLineDist3 = Vector.Multiply(vecPerpLine, vecRect3) - dDistPerpLine;
double dPerpLineDist4 = Vector.Multiply(vecPerpLine, vecRect4) - dDistPerpLine;
double dMinPerpLineDist = Math.Min(dPerpLineDist1, Math.Min(dPerpLineDist2,
    Math.Min(dPerpLineDist3, dPerpLineDist4)));
double dMaxPerpLineDist = Math.Max(dPerpLineDist1, Math.Max(dPerpLineDist2,
    Math.Max(dPerpLineDist3, dPerpLineDist4)));
如果所有距离都为正,或所有距离都为负,则矩形位于直线的一侧或另一侧,因此没有交点。(零范围矩形被视为不与任何线段相交。)

如果矩形的点不在线段的范围内,则没有交点

if (dMaxLineDist <= 0.0 || dMinLineDist >= dLengthLine)
    /* no intersection */;
if(dMaxLineDist=dllengline)
/*无交叉路口*/;

我相信这就足够了。

直线的可能重复部分称为线段有一种情况没有按照@templatetypedef给出的思路处理:线段的两个端点位于矩形内的情况。但是这种情况很容易检查:<代码> x1 > @ rrnuu,除了如果包含在矩形中,它不与矩形相交。@ MalkPo:这取决于如果你考虑矩形,如果直线段直接穿过矩形的一个角,从而导致矩形两侧接触该角的相交检查失败,那么处理这种情况的最佳方法是什么?如果直线碰到角,碰撞检查不会通过吗?假设每个边都有一个包含检查,你应该会没事的。我一直在想这个。。。这是不对的。所有顶点都可以位于直线的同一侧,但仍会生成符号相反的点积。此外,使用方向向量也不考虑直线的实际位置。可以选择两条平行线:一条与矩形相交,另一条不相交。由于它们的方向相同,四个点积将为两条线产生相同的值,这显然与定理相矛盾。我必须-1这个,虽然最初的想法很好。这个方法可以推广到3D吗?假设我们有矩形的法线。利用线段方向和法线,我们可以得到第三个方向,它垂直于这两个方向,所以我们可以计算“矢量线”。Rest使用点积和距离减法。这对我来说是有道理的。有人能评论我的想法吗?
double dPerpLineDist1 = Vector.Multiply(vecPerpLine, vecRect1) - dDistPerpLine;
double dPerpLineDist2 = Vector.Multiply(vecPerpLine, vecRect2) - dDistPerpLine;
double dPerpLineDist3 = Vector.Multiply(vecPerpLine, vecRect3) - dDistPerpLine;
double dPerpLineDist4 = Vector.Multiply(vecPerpLine, vecRect4) - dDistPerpLine;
double dMinPerpLineDist = Math.Min(dPerpLineDist1, Math.Min(dPerpLineDist2,
    Math.Min(dPerpLineDist3, dPerpLineDist4)));
double dMaxPerpLineDist = Math.Max(dPerpLineDist1, Math.Max(dPerpLineDist2,
    Math.Max(dPerpLineDist3, dPerpLineDist4)));
if (dMinPerpLineDist <= 0.0 && dMaxPerpLineDist <= 0.0
        || dMinPerpLineDist >= 0.0 && dMaxPerpLineDist >= 0.0)
    /* no intersection */;
double dDistLine1 = Vector.Multiply(vecLine, vecRect1) - dDistLine;
double dDistLine2 = Vector.Multiply(vecLine, vecRect2) - dDistLine;
double dDistLine3 = Vector.Multiply(vecLine, vecRect3) - dDistLine;
double dDistLine4 = Vector.Multiply(vecLine, vecRect4) - dDistLine;
double dMinLineDist = Math.Min(dDistLine1, Math.Min(dDistLine2,
    Math.Min(dDistLine3, dDistLine4)));
double dMaxLineDist = Math.Max(dDistLine1, Math.Max(dDistLine2,
    Math.Max(dDistLine3, dDistLine4)));
if (dMaxLineDist <= 0.0 || dMinLineDist >= dLengthLine)
    /* no intersection */;