Calculando o produto cruzado de um vetor 2D

87

Da wikipedia:

o produto vetorial é uma operação binária em dois vetores em um espaço euclidiano tridimensional que resulta em outro vetor perpendicular ao plano que contém os dois vetores de entrada.

Dado que a definição é definida apenas em três ( ou sete, um e zero ) dimensões, como calcular o produto vetorial de dois vetores 2D?

Eu vi duas implementações. Um retorna um novo vetor (mas só aceita um único vetor), o outro retorna um escalar (mas é um cálculo entre dois vetores).

Implementação 1 (retorna um escalar):

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

Implementação 2 (retorna um vetor):

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

Por que as implementações variadas? Para que eu usaria a implementação escalar? Para que eu usaria a implementação do vetor?

O motivo de minha pergunta é porque estou escrevendo uma classe Vector2D e não sei qual método usar.

Zack, o Humano
fonte
10
A implementação 2 está errada. Você precisa de dois vetores para formar um produto vetorial.
bobobobo
7
A implementação 2 gira o vetor dado v em -90 graus. Substitua -90 em x' = x cos θ - y sin θe y' = x sin θ + y cos θ. Outra variação dessa implementação seria return Vector2D(-v.Y, v.X);girar v em +90 graus.
legends2k de
3
@ legends2k: Vale a pena observar que a implementação 2 é uma extensão do uso do determinante para avaliar o produto vetorial: basta remover a última linha e coluna. Tal extensão sempre possui N-1operandos para Ndimensões.
Tim Čas
4
A implementação 1 calcula a magnitude do produto cruzado.
Mateen Ulhaq
@MateenUlhaq mais ou menos, é a " magnitude assinada "
Moritz Mahringer

Respostas:

101

A implementação 1 retorna a magnitude do vetor que resultaria de um produto cruzado 3D regular dos vetores de entrada, tomando seus valores Z implicitamente como 0 (isto é, tratando o espaço 2D como um plano no espaço 3D). O produto vetorial 3D será perpendicular a esse plano e, portanto, terá 0 componentes X e Y (portanto, o escalar retornado é o valor Z do vetor de produto vetorial 3D).

Observe que a magnitude do vetor resultante do produto vetorial 3D também é igual à área do paralelogramo entre os dois vetores, o que dá à Implementação 1 outro propósito. Além disso, essa área é sinalizada e pode ser usada para determinar se a rotação de V1 para V2 se move no sentido anti-horário ou horário. Deve-se notar também que a implementação 1 é o determinante da matriz 2x2 construída a partir desses dois vetores.

A implementação 2 retorna um vetor perpendicular ao vetor de entrada ainda no mesmo plano 2D. Não é um produto vetorial no sentido clássico, mas é consistente no sentido de "me dê um vetor perpendicular".

Observe que o espaço euclidiano 3D é fechado sob a operação de produto vetorial - ou seja, um produto vetorial de dois vetores 3D retorna outro vetor 3D. Ambas as implementações 2D acima são inconsistentes de uma forma ou de outra.

Espero que isto ajude...

Drew Hall
fonte
7
Na verdade, a implementação 2 é o produto vetorial de ve o vetor unitário apontando para cima na direção z.
mattiast
@mattiast: True. É exatamente assim que a operação 2D 'perp' é descrita em 3D.
Drew Hall,
@mattiast: A implementação 2 pode ser considerada uma extensão do uso de um determinante para calcular o produto vetorial --- basta remover a última linha e coluna. Deve-se notar que a implementação 1 é equivalente a:, DotProduct(a, CrossProduct(b))que é (muito elegantemente!) Consistente com a noção de um "produto escalar perpendicular" (que é o que essa implementação 1 também é [e talvez mais precisamente] conhecida como!).
Tim Čas
Em seu primeiro parágrafo, a magnitude é o valor absoluto do que é retornado. Não é exatamente a mesma coisa que o componente Z. Como você apontou no segundo parágrafo, você pode usar o sinal da cruz para repelir vampiros ... err, quero dizer detectar quando um vetor está saindo versus entrando no contorno de um polígono, por exemplo.
Peter Cordes,
68

Resumindo: é uma notação abreviada para um hack matemático.

Explicação longa:

Você não pode fazer um produto vetorial com vetores no espaço 2D. A operação não está definida lá.

No entanto, muitas vezes é interessante avaliar o produto vetorial de dois vetores assumindo que os vetores 2D são estendidos para 3D definindo sua coordenada z para zero. Isso é o mesmo que trabalhar com vetores 3D no plano xy.

Se você estender os vetores dessa maneira e calcular o produto vetorial de um par de vetores estendidos, você notará que apenas o componente z tem um valor significativo: x e y sempre serão zero.

Essa é a razão pela qual o componente z do resultado geralmente é simplesmente retornado como um escalar. Este escalar pode, por exemplo, ser usado para encontrar o enrolamento de três pontos no espaço 2D.

De um ponto de vista matemático puro, o produto vetorial no espaço 2D não existe, a versão escalar é o hack e um produto vetorial 2D que retorna um vetor 2D não faz nenhum sentido.

Nils Pipenbrinck
fonte
"por exemplo, ser usado para encontrar o enrolamento de três pontos no espaço 2D" @Nils Pipenbrinck, o que você quer dizer com enrolamento neste contexto?
Nader Belal
1
@NaderBelal Suponho que enrolar aqui implicaria - se formos do ponto a para b para c, estaremos indo no sentido horário ou anti-horário, em termos do ângulo que acabamos de cruzar.
Amit Tomar
12

Outra propriedade útil do produto vetorial é que sua magnitude está relacionada ao seno do ângulo entre os dois vetores:

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

ou

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

Portanto, na implementação 1 acima, se ae bsão conhecidos de antemão como vetores unitários, o resultado dessa função é exatamente esse valor seno ().

Alnitak
fonte
1
... que também é o dobro da área do triângulo entre o vetor a e o vetor b.
Tim Lovell-Smith
5

A implementação 1 é o produto escalar perp dos dois vetores. A melhor referência que conheço para gráficos 2D é a excelente série Graphics Gems . Se você está fazendo scratch trabalho 2D, é muito importante ter esses livros. O Volume IV tem um artigo chamado "Os prazeres dos produtos pontuais do perp", que aborda muitos usos dele.

Um dos principais usos do produto escalar perp é obter a escala sindo ângulo entre os dois vetores, assim como o produto escalar retorna a escala cosdo ângulo. É claro que você pode usar produto escalar e produto escalar perp juntos para determinar o ângulo entre dois vetores.

Aqui está um post sobre ele e aqui está o artigo do Wolfram Math World.

Bill Burdick
fonte
3

Estou usando produto vetorial 2d em meu cálculo para encontrar a nova rotação correta para um objeto que está sendo acionado por um vetor de força em um ponto arbitrário em relação ao seu centro de massa. (O escalar Z um.)


fonte
3

Uma operação vetorial 2D útil é um produto vetorial que retorna um escalar. Eu o uso para ver se duas arestas sucessivas em um polígono dobram para a esquerda ou para a direita.

Da 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;
}
Bram
fonte