如果您有两个点(x1,y1)和(x2,y2),表示矩形的两个相对角落,和另外两个点(x3,y3)和(x4,y4),表示线段的两个端点,您如何检查线段是否与矩形相交?
(该线段是仅包含给定端点的线段。它不是由这两个点定义的无限长度线。)
(该线段是仅包含给定端点的线段。它不是由这两个点定义的无限长度线。)
一种非常简单的选择是使用标准算法检查两条线段是否相交,以检查线段是否与构成盒子角落的四个线段中的任何一个相交。 检查两条线段是否相交在计算上非常高效,因此我预计这可以运行得非常快。
希望这能帮到你!
x1 < x3 && x3 < x2 && y1 < y3 && y3 < y2
。 - lrineauPointF
变量a_ptStart
和a_ptEnd
计算该值,使用Vector
:Vector vecLine = new Vector(a_ptEnd.X - a_ptStart.X, a_ptEnd.Y - a_ptStart.Y);
double dLengthLine = vecLine.Length;
vecLine /= dLengthLine;
double dDistLine = Vector.Multiply(vecLine, new Vector(a_ptStart.X, a_ptStart.Y));
您还需要计算线段的垂直向量及其与原点的距离。通过旋转单位向量90°很容易。
Vector vecPerpLine = new Vector(-vecLine.Y, vecLine.X);
double dDistPerpLine = Vector.Multiply(vecPerpLine, new Vector(a_ptStart.X, a_ptStart.Y));
vecRect1
、vecRect2
、vecRect3
和 vecRect4
的向量变量表示,计算该线段与目标边界矩形的四个角之间的距离: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 */;
我相信这已经足够了。
使用线段的方向向量获取矩形的所有4个顶点(角落)的点积。如果所有4个值都具有相同符号,则所有顶点位于该直线的同一侧(不是线段,而是无限线),因此该直线不与矩形相交。这种方法仅适用于2D交集检测。这可用于快速过滤大部分对象(仅使用乘法和加法)。对于线段而非直线,您必须进行进一步的检查。