Calcular el producto cruzado de un vector 2D

85

De wikipedia:

el producto cruzado es una operación binaria sobre dos vectores en un espacio euclidiano tridimensional que da como resultado otro vector que es perpendicular al plano que contiene los dos vectores de entrada.

Dado que la definición solo se define en tres ( o siete, uno y cero ) dimensiones, ¿cómo se calcula el producto cruzado de dos vectores 2d?

He visto dos implementaciones. Uno devuelve un nuevo vector (pero solo acepta un único vector), el otro devuelve un escalar (pero es un cálculo entre dos vectores).

Implementación 1 (devuelve un escalar):

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

Implementación 2 (devuelve un vector):

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

¿Por qué las diferentes implementaciones? ¿Para qué usaría la implementación escalar? ¿Para qué usaría la implementación del vector?

La razón por la que pregunto es porque yo mismo estoy escribiendo una clase de Vector2D y no sé qué método usar.

Zack el humano
fuente
10
La implementación 2 es incorrecta. Necesita dos vectores para formar un producto cruzado.
bobobobo
7
La implementación 2 rota el vector v dado en -90 grados. Sustituya -90 en x' = x cos θ - y sin θy y' = x sin θ + y cos θ. Otra variación de esta implementación sería a la return Vector2D(-v.Y, v.X);que se rota v en +90 grados.
legends2k
3
@ legends2k: Vale la pena señalar que la implementación 2 es una extensión del uso del determinante para evaluar el producto cruzado : simplemente elimine la última fila y columna. Tal extensión siempre tiene N-1operandos para Ndimensiones.
Tim Čas
4
La implementación 1 calcula la magnitud del producto cruzado.
Mateen Ulhaq
@MateenUlhaq, es la " magnitud firmada "
Moritz Mahringer

Respuestas:

100

La implementación 1 devuelve la magnitud del vector que resultaría de un producto cruzado 3D regular de los vectores de entrada, tomando sus valores Z implícitamente como 0 (es decir, tratando el espacio 2D como un plano en el espacio 3D). El producto cruzado 3D será perpendicular a ese plano y, por lo tanto, tendrá 0 componentes X e Y (por lo tanto, el escalar devuelto es el valor Z del vector del producto cruzado 3D).

Tenga en cuenta que la magnitud del vector resultante del producto cruzado 3D también es igual al área del paralelogramo entre los dos vectores, lo que le da a la Implementación 1 otro propósito. Además, esta área está firmada y se puede usar para determinar si la rotación de V1 a V2 se mueve en sentido antihorario o en sentido horario. También debe tenerse en cuenta que la implementación 1 es el determinante de la matriz 2x2 construida a partir de estos dos vectores.

La implementación 2 devuelve un vector perpendicular al vector de entrada aún en el mismo plano 2D. No es un producto cruzado en el sentido clásico, pero consistente en el sentido de "dame un vector perpendicular".

Tenga en cuenta que el espacio euclidiano 3D está cerrado bajo la operación de producto cruzado, es decir, un producto cruzado de dos vectores 3D devuelve otro vector 3D. Ambas implementaciones 2D anteriores son inconsistentes con eso de una forma u otra.

Espero que esto ayude...

Drew Hall
fuente
6
En realidad, la implementación 2 es el producto cruzado de v y el vector unitario apuntando hacia arriba en la dirección z.
Mattiast
@mattiast: Cierto. Así es exactamente como se describe la operación 2D 'perpetrador' en 3D.
Drew Hall
@mattiast: La implementación 2 se puede considerar como una extensión del uso de un determinante para calcular el producto cruzado, simplemente elimine la última fila y columna. Cabe señalar que la implementación 1 es equivalente a:, DotProduct(a, CrossProduct(b))que es (¡muy elegantemente!) Consistente con la noción de un "producto punto perpendicular" (que es lo que también se conoce [y quizás con más precisión] esa implementación 1).
Tim Čas
En su primer párrafo, la magnitud es el valor absoluto de lo que se devuelve. No es exactamente lo mismo que el componente Z. Como señala en el 2º párrafo, puede usar el signo de la cruz para repeler vampiros ... eh, me refiero a detectar cuando un vector está saliendo o entrando en el contorno de un polígono, por ejemplo.
Peter Cordes
68

En resumen: es una notación abreviada para un truco matemático.

Explicación larga:

No puede hacer un producto cruzado con vectores en el espacio 2D. La operación no está definida allí.

Sin embargo, a menudo es interesante evaluar el producto cruzado de dos vectores asumiendo que los vectores 2D se extienden a 3D estableciendo su coordenada z en cero. Esto es lo mismo que trabajar con vectores 3D en el plano xy.

Si extiende los vectores de esa manera y calcula el producto cruzado de un par de vectores tan extendido, notará que solo el componente z tiene un valor significativo: xey siempre serán cero.

Esa es la razón por la que el componente z del resultado a menudo se devuelve simplemente como un escalar. Este escalar se puede utilizar, por ejemplo, para encontrar el devanado de tres puntos en el espacio 2D.

Desde un punto de vista matemático puro, el producto cruzado en el espacio 2D no existe, la versión escalar es el truco y un producto cruzado 2D que devuelve un vector 2D no tiene ningún sentido.

Nils Pipenbrinck
fuente
"por ejemplo, se puede utilizar para encontrar el devanado de tres puntos en el espacio 2D" @Nils Pipenbrinck, ¿a qué te refieres con enrollado en este contexto?
Nader Belal
1
@NaderBelal Supongo que enrollar aquí implicaría: si vamos del punto a al b ac, estaremos en sentido horario o antihorario, en términos del ángulo que acabamos de abarcar.
Amit Tomar
12

Otra propiedad útil del producto cruzado es que su magnitud está relacionada con el seno del ángulo entre los dos vectores:

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

o

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

Así, en la ejecución 1 anterior, si ay bson conocidos de antemano para ser vectores unitarios a continuación, el resultado de esa función es exactamente eso sine valor ().

Alnitak
fuente
1
... que también es el doble del área del triángulo entre el vector ay el vector b.
Tim Lovell-Smith
5

La implementación 1 es el producto de puntos perp de los dos vectores. La mejor referencia que conozco para gráficos 2D es la excelente serie Graphics Gems . Si está haciendo trabajo en 2D desde cero, es realmente importante tener estos libros. El Volumen IV tiene un artículo llamado "Los placeres de los productos Perp Dot" que repasa muchos de sus usos.

Un uso importante del producto escalar perp es obtener la escala sindel ángulo entre los dos vectores, al igual que el producto escalar devuelve la escala cosdel ángulo. Por supuesto, puede usar el producto escalar y el producto escalar perp juntos para determinar el ángulo entre dos vectores.

Aquí hay una publicación al respecto y aquí está el artículo de Wolfram Math World.

Bill Burdick
fuente
3

Estoy usando un producto cruzado 2d en mi cálculo para encontrar la nueva rotación correcta para un objeto sobre el que actúa un vector de fuerza en un punto arbitrario en relación con su centro de masa. (El escalar Z uno.)


fuente
3

Una operación de vector 2D útil es un producto cruzado que devuelve un escalar. Lo uso para ver si dos bordes sucesivos en un polígono se doblan hacia la izquierda o hacia la derecha.

De la fuente 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
fuente