Um zu verstehen, wie man die Formel zum Testen, ob ein Liniensegment ein Rechteck schneidet, herleitet, ist es wichtig, sich an die Eigenschaften des vector dot product zu erinnern.
Stellen Sie das Liniensegment als Einheitsvektor und einen Abstand zwischen dem Startpunkt des Liniensegments und dem Ursprung dar. Hier einige C# -Code zu berechnen, dass von den PointF
Variablen a_ptStart
und a_ptEnd
unter Verwendung einer 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));
Sie werden auch die senkrechte Vektor berechnen müssen, und seine Entfernung vom Ursprung, für das Liniensegment. Ein Einheitsvektor um 90 ° zu drehen ist easy.
Vector vecPerpLine = new Vector(-vecLine.Y, vecLine.X);
double dDistPerpLine = Vector.Multiply(vecPerpLine, new Vector(a_ptStart.X, a_ptStart.Y));
die vier Ecken des Rechtecks Unter der Annahme, sind in Vector
Variablen namens vecRect1
, vecRect2
, vecRect3
und vecRect4
, berechnen die distance zwischen dem Liniensegment und alle vier Ecken des Begrenzungsrechteck des Ziels:
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)));
Wenn alle Entfernungen positiv sind oder alle Entfernungen negativ sind, befindet sich das Rechteck auf der einen oder anderen Seite der Linie, also gibt es keinen Schnittpunkt. (Zero-Ausmaß Rechtecken werden als nicht mit einem Liniensegment zu schneiden.)
if (dMinPerpLineDist <= 0.0 && dMaxPerpLineDist <= 0.0
|| dMinPerpLineDist >= 0.0 && dMaxPerpLineDist >= 0.0)
/* no intersection */;
nächstes Projekt aller vier Ecken des Begrenzungsrechtecks des Ziels auf das Liniensegment. Dies gibt uns den Abstand zwischen dem Ursprung der Linie und der Projektion der Rechteckecke auf dieser Linie.
Wenn die Punkte des Rechtecks nicht in die Ausdehnung des Liniensegments fallen, dann gibt es keinen Schnittpunkt.
if (dMaxLineDist <= 0.0 || dMinLineDist >= dLengthLine)
/* no intersection */;
Ich glaube, dass ausreichend ist.
möglich Duplikat von [Linien-Rechteck-Kollisionserkennung] (http://stackoverflow.com/questions/2368211/line-rectangle-collision-detection) – templatetypedef
Ihre Linie heißt Segment – kassak