Być może jest to raczej pytanie matematyczne niż pytanie programistyczne, ale próbowałem wdrożyć algorytm obracających się suwaków w XNA.Odnajdywanie zorientowanego obwiedni kadłuba wypukłego w XNA przy użyciu obrotowych suwaków
Wydedukowałem wypukły kadłub z mojego zestawu punktów za pomocą monotonnego łańcucha, jak to opisano na wikipedii.
Teraz staram się modelować mój algorytm, aby znaleźć po jednym ÖBB znaleźć tutaj: http://www.cs.purdue.edu/research/technical_reports/1983/TR%2083-463.pdf
Jednak nie rozumiem, jakie metody DOTPR i CROSSPR wymienia na ostatniej stronie mają wracać.
Rozumiem, jak uzyskać produkt punktowy z dwóch punktów i produktu krzyżowego z dwóch punktów, ale wygląda na to, że te funkcje mają zwracać produkty punktowe i krzyżowe dwóch krawędzi/segmentów linii. Moja znajomość matematyki jest wprawdzie ograniczona, ale to jest mój najlepszy przypuszczenie, co algorytm szuka
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;
}
Jednak, kiedy stosować te same metody, jak jest w tej części mojego kodu ...
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);
}
..To zwraca ten sam indeks, j, k, kiedy dać mu zestaw testowy punktów:
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),
};
uwaga, że zadzwonię polygon.Reverse umieszczenie tych punktów w porządku lewo jak ind zawarty w dokumencie technicznym z perdue.edu. Mój algorytm wyszukiwania kadłuba wypukłego zbioru punktów generuje listę punktów w kolejności przeciwnej do ruchu wskazówek zegara, ale przyjmuje, że y < 0 jest wyższe niż y> 0, ponieważ podczas rysowania na ekranie 0,0 jest lewym górnym rogiem . Cofanie listy wydaje się wystarczające. Usuwam również duplikat na końcu.
Po tym procesie dane przedstawia się następująco:
- 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)
Ten test nie powiedzie się w pierwszej pętli gdy j wynosi 0 jest równy 3. Okazuje się, że przekrój produktu na linii (115,14) do (204,63) i linia (204,63) do (199,68) wynosi 0. Następnie okazuje się, że produkt kropki z tych samych linii również wynosi 0, więc j i k dzielą ten sam indeks.
W przeciwieństwie do tego, kiedy dana ten zestaw testowy: 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
Mój kod pomyślnie zwraca ten ÖBB: 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
Czytałem nad algorytmem C++ znalezionego na http://www.geometrictools.com/LibMathematics/Containment/Wm5ContMinBox2.cpp ale jestem zbyt gęsta, aby podążaj za tym całkowicie.Wydaje się również, że różni się znacznie od tej opisanej w powyższym artykule.
Czy ktoś wie, jaki krok pomijam lub widzę błąd w moim kodzie do znalezienia produktu kropki i iloczynu dwóch segmentów linii? Czy ktoś pomyślnie zaimplementował ten kod wcześniej w C# i ma przykład?
ten wielokąt Lista wielokąta = nowy Lista() {nowy Vector2 (2, 0), nowe Vector2 (0, 2), nowe Vector2 (2, 4), nowe Vector2 (4, 2)}; jest przeciwnie do ruchu wskazówek zegara, prawda? 0,2 jest w lewo i w dół od 2,0. 2,4 znajduje się po prawej stronie i poniżej 0,2. 4,2 jest po prawej i od 2,4. 2,0 jest po lewej stronie i wyżej od 4,2. Jest to diament przeciwny do ruchu wskazówek zegara. – MattB
Czekaj. Pracuję z grami wideo od tak dawna, że zapomniałem, że ludzie zwykle pracują w pierwszym kwadrancie, a nie w czwartym, gdzie im niższa wartość y, tym wyższa. Mam nadzieję, że to mój problem. – MattB
To było to! Dziękuję bardzo. Jestem zawstydzony, że to było takie proste. – MattB