Obliczanie iloczynu wektorowego 2D

85

Z Wikipedii:

iloczyn poprzeczny jest operacją binarną na dwóch wektorach w trójwymiarowej przestrzeni euklidesowej, w wyniku której powstaje inny wektor, który jest prostopadły do ​​płaszczyzny zawierającej dwa wektory wejściowe.

Biorąc pod uwagę, że definicja jest zdefiniowana tylko w trzech ( lub siedmiu, jednym i zera ) wymiarach, w jaki sposób można obliczyć iloczyn poprzeczny dwóch wektorów 2D?

Widziałem dwie implementacje. Jeden zwraca nowy wektor (ale akceptuje tylko jeden wektor), drugi zwraca wartość skalarną (ale jest obliczeniem między dwoma wektorami).

Implementacja 1 (zwraca wartość skalarną):

float CrossProduct(const Vector2D & v1, const Vector2D & v2) const
{
    return (v1.X*v2.Y) - (v1.Y*v2.X);
}

Implementacja 2 (zwraca wektor):

Vector2D CrossProduct(const Vector2D & v) const
{
    return Vector2D(v.Y, -v.X);
}

Po co różne implementacje? Do czego użyłbym implementacji skalarnej? Do czego użyłbym implementacji wektora?

Pytam, ponieważ sam piszę klasę Vector2D i nie wiem, której metody użyć.

Zack The Human
źródło
10
Implementacja 2 jest nieprawidłowa. Do utworzenia iloczynu krzyżowego potrzebne są dwa wektory.
bobobobo
7
Implementacja 2 obraca dany wektor v o -90 stopni. Zamień -90 w x' = x cos θ - y sin θi y' = x sin θ + y cos θ. Inną odmianą tej implementacji byłoby return Vector2D(-v.Y, v.X);obrócenie v o +90 stopni.
legends2k
3
@ legends2k: Warto zauważyć, że implementacja 2 jest rozszerzeniem wykorzystania wyznacznika do oceny iloczynu krzyżowego : wystarczy usunąć ostatni wiersz i kolumnę. Takie rozszerzenie zawsze ma N-1operandy dla Nwymiarów.
Tim Čas
4
Implementacja 1 oblicza wielkość iloczynu krzyżowego.
Mateen Ulhaq
@MateenUlhaq w pewnym sensie to „ podpisana wielkość”
Moritz Mahringer

Odpowiedzi:

100

Implementacja 1 zwraca wielkość wektora, który wynikałby z regularnego produktu krzyżowego 3D wektorów wejściowych, przyjmując ich wartości Z pośrednio jako 0 (tj. Traktując przestrzeń 2D jako płaszczyznę w przestrzeni 3D). Iloczyn trójwymiarowy będzie prostopadły do ​​tej płaszczyzny, a zatem będzie miał 0 składowych X i Y (stąd zwracany skalar to wartość Z trójwymiarowego wektora iloczynowego).

Zauważ, że wielkość wektora wynikająca z iloczynu 3D jest również równa powierzchni równoległoboku między dwoma wektorami, co nadaje Implementacji 1 inny cel. Ponadto obszar ten jest oznaczony i może być użyty do określenia, czy obrót z V1 do V2 porusza się w kierunku przeciwnym do ruchu wskazówek zegara, czy w kierunku zgodnym z ruchem wskazówek zegara. Należy również zauważyć, że implementacja 1 jest wyznacznikiem macierzy 2x2 zbudowanej z tych dwóch wektorów.

Implementacja 2 zwraca wektor prostopadły do ​​wektora wejściowego wciąż znajdującego się na tej samej płaszczyźnie 2D. Nie jest to iloczyn poprzeczny w klasycznym sensie, ale spójny w sensie „podaj mi wektor prostopadły”.

Zwróć uwagę, że trójwymiarowa przestrzeń euklidesowa jest zamknięta podczas operacji krzyżowej - to znaczy iloczyn dwóch wektorów 3D zwraca kolejny wektor 3D. Obie powyższe implementacje 2D są z tym w jakiś sposób niezgodne.

Mam nadzieję że to pomoże...

Drew Hall
źródło
6
W rzeczywistości implementacja 2 to iloczyn v i wektora jednostkowego skierowanego w górę w kierunku z.
mattiast
@mattiast: True. Dokładnie tak jest opisana operacja 2D „perp” w 3D.
Drew Hall
@mattiast: Implementacja 2 może być traktowana jako rozszerzenie użycia wyznacznika do obliczenia iloczynu krzyżowego - wystarczy usunąć ostatni wiersz i kolumnę. Należy zauważyć, że implementacja 1 jest równoważna z:, DotProduct(a, CrossProduct(b))co jest (bardzo elegancko!) Zgodne z pojęciem „prostopadłego iloczynu skalarnego” (co jest tym, czym ta implementacja 1 jest również [i być może dokładniej] znana jako!).
Tim Čas
W pierwszym akapicie wielkość jest wartością bezwzględną zwracanej kwoty. To nie to samo, co komponent Z. Jak wskazałeś w drugim akapicie, możesz użyć znaku krzyża, aby odstraszyć wampiry ... eee, mam na myśli, na przykład, wykrycie, kiedy wektor opuszcza, a kiedy wchodzi w kontur wielokąta.
Peter Cordes
68

W skrócie: jest to skrótowa notacja dla matematycznego triku.

Długie wyjaśnienie:

Nie można wykonać iloczynu krzyżowego z wektorami w przestrzeni 2D. Operacja nie jest tam zdefiniowana.

Jednak często warto ocenić iloczyn poprzeczny dwóch wektorów, zakładając, że wektory 2D są rozszerzone do 3D przez ustawienie ich współrzędnej z na zero. Działa to tak samo, jak praca z wektorami 3D na płaszczyźnie xy.

Jeśli rozszerzysz wektory w ten sposób i obliczysz iloczyn poprzeczny takiej rozszerzonej pary wektorów, zauważysz, że tylko składnik z ma sensowną wartość: x i y zawsze będą wynosić zero.

To jest powód, dla którego składowa z wyniku jest często zwracana jako skalar. Tego skalara można na przykład użyć do znalezienia uzwojenia trzech punktów w przestrzeni 2D.

Z czysto matematycznego punktu widzenia iloczyn krzyżowy w przestrzeni 2D nie istnieje, wersja skalarna to hack, a iloczyn krzyżowy 2D, który zwraca wektor 2D, nie ma żadnego sensu.

Nils Pipenbrinck
źródło
„na przykład posłużyć do znalezienia uzwojenia trzech punktów w przestrzeni 2D” @Nils Pipenbrinck, co w tym kontekście oznacza uzwojenie?
Nader Belal
1
@NaderBelal Przypuszczam, że uzwojenie tutaj oznaczałoby - jeśli przejdziemy od punktu a do b do c, będziemy szli zgodnie z ruchem wskazówek zegara, czy przeciwnie do ruchu wskazówek zegara, biorąc pod uwagę kąt, który właśnie obejmowaliśmy.
Amit Tomar,
12

Inną użyteczną właściwością iloczynu krzyżowego jest to, że jego wielkość jest związana z sinusem kąta między dwoma wektorami:

| axb | = | a | . | b | . sinus (theta)

lub

sinus (theta) = | axb | / (| a |. | b |)

Tak więc, w realizacji 1 powyżej, jeżeli ai bsą znane z wyprzedzeniem, aby mieć wektor jednostkowy to wynik tej funkcji jest dokładnie to sine wartość ().

Alnitak
źródło
1
... który jest również dwukrotnie większy od obszaru trójkąta między wektorem a i wektorem b.
Tim Lovell-Smith
5

Implementacja 1 to iloczyn skalarny dwóch wektorów. Najlepszym odniesieniem do grafiki 2D, jaką znam, jest doskonała seria Graphics Gems . Jeśli wykonujesz od podstaw prace 2D, posiadanie tych książek jest naprawdę ważne. Tom IV zawiera artykuł zatytułowany „Przyjemności produktów Perp Dot”, który omawia wiele zastosowań.

Jednym z głównych zastosowań iloczynu punktowego jest uzyskanie wyskalowania sinkąta między dwoma wektorami, tak jak iloczyn skalarny zwraca wyskalowany coskąt. Oczywiście możesz użyć iloczynu skalarnego i iloczynu skalarnego w celu określenia kąta między dwoma wektorami.

Oto post na ten temat, a tutaj artykuł Wolfram Math World.

Bill Burdick
źródło
3

W moich obliczeniach używam iloczynu 2-wymiarowego, aby znaleźć nowy prawidłowy obrót obiektu, na który działa wektor siły w dowolnym punkcie względem środka masy. (Skalarny Z jeden.)


źródło
3

Użyteczną operacją wektorową 2D jest iloczyn krzyżowy, który zwraca skalar. Używam go do sprawdzenia, czy dwie kolejne krawędzie w wielokącie wyginają się w lewo czy w prawo.

Ze źródła Chipmunk2D :

/// 2D vector cross product analog.
/// The cross product of 2D vectors results in a 3D vector with only a z component.
/// This function returns the magnitude of the z value.
static inline cpFloat cpvcross(const cpVect v1, const cpVect v2)
{
        return v1.x*v2.y - v1.y*v2.x;
}
Bram
źródło