Calcolo del prodotto incrociato di un vettore 2D


87

Da wikipedia:

il prodotto incrociato è un'operazione binaria su due vettori in uno spazio euclideo tridimensionale che risulta in un altro vettore perpendicolare al piano contenente i due vettori di input.

Dato che la definizione è definita solo in tre ( o sette, una e zero ) dimensioni, come si calcola il prodotto incrociato di due vettori 2d?

Ho visto due implementazioni. Uno restituisce un nuovo vettore (ma accetta solo un singolo vettore), l'altro restituisce uno scalare (ma è un calcolo tra due vettori).

Implementazione 1 (restituisce uno scalare):

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

Implementazione 2 (restituisce un vettore):

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

Perché le diverse implementazioni? Per cosa dovrei usare l'implementazione scalare? Per cosa utilizzerei l'implementazione del vettore?

Il motivo per cui lo chiedo è perché sto scrivendo una classe Vector2D da solo e non so quale metodo usare.


10
L'implementazione 2 è sbagliata. Sono necessari due vettori per formare un prodotto incrociato.
bobobobo

7
L'implementazione 2 ruota il vettore dato v di -90 gradi. Sostituisci -90 in x' = x cos θ - y sin θe y' = x sin θ + y cos θ. Un'altra variazione di questa implementazione sarebbe quella di return Vector2D(-v.Y, v.X);ruotare v di +90 gradi.
legends2k

3
@ legends2k: Vale la pena notare che l'implementazione 2 è un'estensione dell'utilizzo del determinante per valutare il prodotto incrociato : è sufficiente rimuovere l'ultima riga e colonna. Tale estensione ha sempre N-1operandi per le Ndimensioni.
Tim Čas

4
L'implementazione 1 calcola l' ampiezza del prodotto incrociato.
Mateen Ulhaq

@MateenUlhaq sorta di, è il " firmato grandezza"
Moritz Mahringer

Risposte:


101

L'implementazione 1 restituisce la grandezza del vettore che risulterebbe da un prodotto incrociato 3D regolare dei vettori di input, assumendo i loro valori Z implicitamente come 0 (cioè trattando lo spazio 2D come un piano nello spazio 3D). Il prodotto incrociato 3D sarà perpendicolare a quel piano e quindi avrà 0 componenti X e Y (quindi lo scalare restituito è il valore Z del vettore prodotto incrociato 3D).

Si noti che l'ampiezza del vettore risultante dal prodotto incrociato 3D è anche uguale all'area del parallelogramma tra i due vettori, il che fornisce all'implementazione 1 un altro scopo. Inoltre, quest'area è contrassegnata e può essere utilizzata per determinare se la rotazione da V1 a V2 si muove in senso antiorario o orario. Va anche notato che l'implementazione 1 è il determinante della matrice 2x2 costruita da questi due vettori.

L'implementazione 2 restituisce un vettore perpendicolare al vettore di input ancora nello stesso piano 2D. Non un prodotto incrociato nel senso classico ma coerente nel senso "dammi un vettore perpendicolare".

Si noti che lo spazio euclideo 3D è chiuso sotto l'operazione di prodotto incrociato, ovvero un prodotto incrociato di due vettori 3D restituisce un altro vettore 3D. Entrambe le implementazioni 2D di cui sopra non sono coerenti con quella in un modo o nell'altro.

Spero che sia di aiuto...


7
In realtà, l'implementazione 2 è un prodotto incrociato di ve il vettore unitario rivolto verso l'alto nella direzione z.
mattiast

@mattiast: True. È esattamente così che viene descritta in 3D l'operazione "perp" 2D.
Drew Hall,

@ mattiast: l'implementazione 2 può essere considerata come un'estensione dell'utilizzo di un determinante per calcolare il prodotto incrociato --- basta rimuovere l'ultima riga e colonna. Va notato che l'implementazione 1 è equivalente a:, DotProduct(a, CrossProduct(b))che è (molto elegantemente!) Coerente con la nozione di "prodotto a punti perpendicolari" (che è ciò che l'implementazione 1 è anche [e forse più accuratamente] conosciuta!).
Tim Čas

Nel tuo primo paragrafo, la grandezza è il valore assoluto di ciò che viene restituito. Non è esattamente la stessa cosa del componente Z. Come fai notare nel 2 ° paragrafo, puoi usare il segno della croce per respingere i vampiri ... ehm, intendo per rilevare quando un vettore sta uscendo o entrando nel contorno di un poligono, per esempio.
Peter Cordes

68

In breve: è una notazione abbreviata per un trucco matematico.

Spiegazione lunga:

Non puoi fare un prodotto incrociato con i vettori nello spazio 2D. L'operazione non è definita lì.

Tuttavia, spesso è interessante valutare il prodotto incrociato di due vettori assumendo che i vettori 2D siano estesi al 3D impostando la loro coordinata z a zero. È lo stesso che lavorare con i vettori 3D sul piano xy.

Se estendi i vettori in questo modo e calcoli il prodotto incrociato di una coppia di vettori così estesa noterai che solo il componente z ha un valore significativo: xey saranno sempre zero.

Questo è il motivo per cui il componente z del risultato viene spesso restituito semplicemente come uno scalare. Questo scalare può ad esempio essere utilizzato per trovare l'avvolgimento di tre punti nello spazio 2D.

Da un puro punto di vista matematico il prodotto incrociato nello spazio 2D non esiste, la versione scalare è l'hack e un prodotto incrociato 2D che restituisce un vettore 2D non ha alcun senso.


"per esempio essere usato per trovare l'avvolgimento di tre punti nello spazio 2D" @Nils Pipenbrinck, cosa intendi per avvolgimento in questo contesto?
Nader Belal

1
@NaderBelal Suppongo che l'avvolgimento qui implicherebbe: se andiamo dal punto a al b al c, andremo in senso orario o antiorario, in termini di angolo che abbiamo appena coperto.
Amit Tomar

12

Un'altra proprietà utile del prodotto incrociato è che la sua grandezza è correlata al seno dell'angolo tra i due vettori:

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

o

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

Quindi, nell'implementazione 1 sopra, se ae bsono noti in anticipo come vettori unitari, il risultato di quella funzione è esattamente quel valore sine ().


1
... che è anche il doppio dell'area del triangolo tra il vettore a e il vettore b.
Tim Lovell-Smith

5

L'implementazione 1 è il prodotto punto perp dei due vettori. Il miglior riferimento che conosco per la grafica 2D è l'eccellente serie Graphics Gems . Se stai facendo lavori 2D zero, è molto importante avere questi libri. Il volume IV ha un articolo intitolato "I piaceri dei prodotti Perp Dot" che ne fa molti usi.

Uno dei principali usi del prodotto punto perp è quello di ottenere la scala sindell'angolo tra i due vettori, proprio come il prodotto puntiforme restituisce la scala cosdell'angolo. Ovviamente puoi usare il prodotto punto e il prodotto punto perp insieme per determinare l'angolo tra due vettori.

Ecco un post su di esso ed ecco l'articolo di Wolfram Math World.


3

Sto usando il prodotto incrociato 2d nel mio calcolo per trovare la nuova rotazione corretta per un oggetto su cui agisce un vettore di forza in un punto arbitrario rispetto al suo centro di massa. (Quello scalare Z).


3

Un'utile operazione vettoriale 2D è un prodotto incrociato che restituisce uno scalare. Lo uso per vedere se due bordi successivi in ​​un poligono si piegano a sinistra oa destra.

Dalla fonte 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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.