Vielleicht ist dies eher eine mathematische Frage als eine Programmierfrage, aber ich habe versucht, den rotierenden Messschieber-Algorithmus in XNA zu implementieren.Finden der orientierten Bounding Box eines konvexen Rumpfes in XNA mit rotierenden Messschieber
Ich habe eine konvexe Hülle von meinem Punktsatz mit einer monotonen Kette abgeleitet, wie in Wikipedia beschrieben.
Jetzt versuche ich meinen Algorithmus zu modellieren die OBB zu finden, nachdem der hier gefunden: http://www.cs.purdue.edu/research/technical_reports/1983/TR%2083-463.pdf
Aber ich verstehe nicht, was die DOTPR und CROSSPR Methoden es auf der letzten Seite erwähnt werden sollen zurückgeben.
Ich verstehe, wie man das Punktprodukt von zwei Punkten und das Kreuzprodukt von zwei Punkten erhält, aber es scheint, dass diese Funktionen die Punkt- und Kreuzprodukte von zwei Kanten/Liniensegmenten zurückgeben sollen. Meine Kenntnisse der Mathematik ist zwar begrenzt, aber das ist meine beste Vermutung, was der Algorithmus sucht
public static float PolygonCross(List<Vector2> polygon, int indexA, int indexB)
{
var segmentA1 = NextVertice(indexA, polygon) - polygon[indexA];
var segmentB1 = NextVertice(indexB, polygon) - polygon[indexB];
float crossProduct1 = CrossProduct(segmentA1, segmentB1);
return crossProduct1;
}
public static float CrossProduct(Vector2 v1, Vector2 v2)
{
return (v1.X * v2.Y - v1.Y * v2.X);
}
public static float PolygonDot(List<Vector2> polygon, int indexA, int indexB)
{
var segmentA1 = NextVertice(indexA, polygon) - polygon[indexA];
var segmentB1 = NextVertice(indexB, polygon) - polygon[indexB];
float dotProduct = Vector2.Dot(segmentA1, segmentB1);
return dotProduct;
}
Allerdings, wenn ich diese Methoden verwenden, wie in diesem Teil meines Codes gerichtet ...
while (PolygonDot(polygon, i, j) > 0)
{
j = NextIndex(j, polygon);
}
if (i == 0)
{
k = j;
}
while (PolygonCross(polygon, i, k) > 0)
{
k = NextIndex(k, polygon);
}
if (i == 0)
{
m = k;
}
while (PolygonDot(polygon, i, m) < 0)
{
m = NextIndex(m, polygon);
}
.it den gleichen Index für j gibt, k, wenn ich ihm einen Test Satz von Punkten geben:
List<Vector2> polygon = new List<Vector2>()
{
new Vector2(0, 138),
new Vector2(1, 138),
new Vector2(150, 110),
new Vector2(199, 68),
new Vector2(204, 63),
new Vector2(131, 0),
new Vector2(129, 0),
new Vector2(115, 14),
new Vector2(0, 138),
};
Beachten sie, dass ich polygon.Reverse diese Punkte im Gegenuhrzeigersinn als ind zu platzieren nennen in dem technischen Dokument von perdue.edu. Mein Algorithmus zum Finden einer konvexen Hülle eines Punktsatzes erzeugt eine Liste von Punkten entgegen dem Uhrzeigersinn, aber unter der Annahme, dass y < 0 höher als y> 0 ist, weil beim Zeichnen auf den Bildschirm 0,0 die obere linke Ecke ist . Das Umkehren der Liste scheint ausreichend zu sein. Ich entferne auch den doppelten Punkt am Ende.
Nach diesem Vorgang werden die Daten:
- Vector2 (115, 14)
- Vector2 (129, 0)
- Vector2 (131, 0)
- Vector2 (204, 63 )
- Vector2 (199, 68)
- Vector2 (150, 110)
- Vector2 (1, 138) 0.123.
- Vector2 (0, 138)
Dieser Test nicht auf der ersten Schleife, wenn i gleich 0 ist und j gleich 3. Es stellt fest, dass das Kreuzprodukt der Linie (115,14) bis (204,63) und die Zeile (204,63) bis (199,68) ist 0. Dann stellt sich heraus, dass das Skalarprodukt der gleichen Zeilen ebenfalls 0 ist, also teilen sich j und k den gleichen Index.
Im Gegensatz dazu, wenn dieser Test-Set gegeben: http://www.wolframalpha.com/input/?i=polygon+%282%2C1%29%2C%281%2C2%29%2C%281%2C3%29%2C%282%2C4%29%2C%284%2C4%29%2C%285%2C3%29%2C%283%2C1%29
Mein Code erfolgreich zurückgegeben wird dieses OBB: http://www.wolframalpha.com/input/?i=polygon+%282.5%2C0.5%29%2C%280.5%2C2.5%29%2C%283%2C5%29%2C%285%2C3%29
ich über den C++ Algorithmus auf http://www.geometrictools.com/LibMathematics/Containment/Wm5ContMinBox2.cpp gefunden gelesen habe, aber ich bin zu dicht folge ihm vollständig.Es scheint auch sehr anders zu sein als das andere, das in dem obigen Papier beschrieben ist.
Weiß jemand, welchen Schritt ich überspringe oder einen Fehler in meinem Code für das Finden des Punktprodukts und des Kreuzprodukts von zwei Liniensegmenten sehe? Hat jemand diesen Code zuvor in C# implementiert und ein Beispiel?
Dieses Polygon: Listenpolygon = neue Liste() {neuer Vektor2 (2, 0), neuer Vektor2 (0, 2), neuer Vektor2 (2, 4), neuer Vektor2 (4, 2),}; ist gegen den Uhrzeigersinn, nicht wahr? 0,2 ist links und unten von 2,0. 2,4 ist rechts und runter von 0,2. 4,2 ist rechts und ab 2,4. 2,0 ist links und ab 4,2. Es ist ein Diamant gegen den Uhrzeigersinn. – MattB
Warten. Ich habe so lange mit Videospielen gearbeitet, dass ich vergessen habe, dass Leute typischerweise im 1. Quadranten und nicht im 4. Quadranten arbeiten, je niedriger der Y-Wert, desto höher ist er. Ich hoffe, das ist mein Problem. – MattB
Das war es! Ich danke dir sehr. Ich bin verlegen, es war so einfach. – MattB