118 votes

Calcul du produit en croix d'un vecteur 2D

De wikipedia :

le produit en croix est une opération binaire sur deux vecteurs dans un fichier tridimensionnel espace euclidien qui donne un autre vecteur perpendiculaire au plan contenant les deux vecteurs d'entrée.

Étant donné que la définition n'est définie qu'en trois ( ou sept, un et zéro ), comment calcule-t-on le produit croisé de deux vecteurs à deux dimensions ?

J'ai vu deux mises en œuvre. L'une renvoie un nouveau vecteur (mais n'accepte qu'un seul vecteur), l'autre renvoie un scalaire (mais c'est un calcul entre deux vecteurs).

Implémentation 1 (renvoie un scalaire) :

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

Implémentation 2 (renvoie un vecteur) :

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

Pourquoi les différentes mises en œuvre ? À quoi servirait l'implémentation scalaire ? À quoi servirait l'implémentation vectorielle ?

La raison de ma question est que je suis en train d'écrire moi-même une classe Vector2D et que je ne sais pas quelle méthode utiliser.

15 votes

L'implémentation 2 est erronée. Vous avez besoin de deux vecteurs pour former un produit en croix.

10 votes

L'implémentation 2 fait tourner le vecteur donné v de -90 degrés. Remplacez -90 par x' = x cos - y sin y y' = x sin + y cos . Une autre variante de cette mise en œuvre consisterait à return Vector2D(-v.Y, v.X); qui est une rotation v de +90 degrés.

3 votes

@legends2k : Il faut noter que l'implémentation 2 est une extension de l'implémentation 2. en utilisant le déterminant pour évaluer le produit en croix : il suffit de supprimer la dernière ligne et la dernière colonne. Une telle extension a toujours N-1 opérandes pour N dimensions.

138voto

Drew Hall Points 15917

L'implémentation 1 renvoie la magnitude du vecteur qui résulterait d'un produit en croix 3D régulier des vecteurs d'entrée, en prenant implicitement leurs valeurs Z comme 0 (c'est-à-dire en traitant l'espace 2D comme un plan dans l'espace 3D). Le produit en croix 3D sera perpendiculaire à ce plan, et aura donc des composantes X et Y nulles (le scalaire renvoyé est donc la valeur Z du vecteur du produit en croix 3D).

Notez que la magnitude du vecteur résultant du produit en croix 3D est également égale à la valeur de zone du parallélogramme entre les deux vecteurs, ce qui donne à l'implémentation 1 un autre but. En outre, cette zone est signée et peut être utilisée pour déterminer si la rotation de V1 à V2 se fait dans le sens inverse des aiguilles d'une montre ou dans le sens des aiguilles d'une montre. Il convient également de noter que l'implémentation 1 est le déterminant de la matrice 2x2 construite à partir de ces deux vecteurs.

L'implémentation 2 renvoie un vecteur perpendiculaire au vecteur d'entrée toujours dans le même plan 2D. Ce n'est pas un produit en croix au sens classique du terme, mais il est cohérent dans le sens "donnez-moi un vecteur perpendiculaire".

Notez que l'espace euclidien 3D est fermé par l'opération du produit en croix, c'est-à-dire qu'un produit en croix de deux vecteurs 3D renvoie un autre vecteur 3D. Les deux implémentations 2D ci-dessus sont incompatibles avec cela d'une manière ou d'une autre.

J'espère que cela vous aidera...

9 votes

En fait, la mise en œuvre 2 est le produit croisé de v et du vecteur unitaire pointant vers le haut dans la direction z.

1 votes

@mattiast : Vrai. C'est exactement comme ça que l'opération "perp" en 2D est décrite en 3D.

0 votes

@mattiast : L'implémentation 2 peut être considérée comme une extension de l'utilisation d'une déterminant pour calculer le produit en croix --- il suffit de supprimer la dernière ligne et la dernière colonne. Il est à noter que l'implémentation 1 est équivalente à : DotProduct(a, CrossProduct(b)) ce qui est (très élégamment !) cohérent avec la notion de "produit scalaire perpendiculaire" (ce que l'implémentation 1 est aussi [et peut-être plus précisément] connue comme !)

96voto

Nils Pipenbrinck Points 41006

En bref : C'est une notation abrégée pour une astuce mathématique.

Longue explication :

Vous ne pouvez pas faire un produit en croix avec des vecteurs dans un espace 2D. L'opération n'y est pas définie.

Cependant, il est souvent intéressant d'évaluer le produit en croix de deux vecteurs en supposant que les vecteurs 2D sont étendus à la 3D en mettant leur coordonnée z à zéro. Cela revient à travailler avec des vecteurs 3D dans le plan xy.

Si vous étendez les vecteurs de cette manière et calculez le produit en croix d'une telle paire de vecteurs étendue, vous remarquerez que seule la composante z a une valeur significative : x et y seront toujours égaux à zéro.

C'est la raison pour laquelle la composante z du résultat est souvent simplement retournée comme un scalaire. Ce scalaire peut par exemple être utilisé pour trouver l'enroulement de trois points dans un espace 2D.

D'un point de vue purement mathématique, le produit en croix dans l'espace 2D n'existe pas, la version scalaire est le hack et un produit en croix 2D qui renvoie un vecteur 2D n'a aucun sens.

0 votes

"par exemple être utilisé pour trouver l'enroulement de trois points dans un espace 2D" @Nils Pipenbrinck, qu'entendez-vous par enroulement dans ce contexte ?

4 votes

@NaderBelal Je suppose que l'enroulement ici impliquerait - si nous allons d'un point a à b à c, irons-nous dans le sens des aiguilles d'une montre ou dans le sens inverse, en termes d'angle que nous venons de parcourir.

14voto

Alnitak Points 143355

Une autre propriété utile du produit en croix est que sa magnitude est liée au sinus de l'angle entre les deux vecteurs :

| a x b | = |a| . |b| . sinus(thêta)

o

sinus(thêta) = | a x b | / (|a| . |b|)

Ainsi, dans la mise en œuvre 1 ci-dessus, si a y b sont connus à l'avance comme étant des vecteurs unitaires, alors le résultat de cette fonction est exactement la valeur de sinus().

3 votes

...qui est aussi le double de l'aire du triangle entre le vecteur a et le vecteur b.

11voto

Bill Burdick Points 169

La mise en œuvre 1 est la perp point produit des deux vecteurs. La meilleure référence que je connaisse en matière de graphisme 2D est l'excellente Gemmes graphiques série. Si vous faites du travail en 2D, c'est realmente important d'avoir ces livres. Le volume IV contient un article intitulé "The Pleasures of Perp Dot Products" qui présente de nombreuses utilisations.

Une des principales utilisations de l perp point produit est d'obtenir l'échelle sin de l'angle entre les deux vecteurs, tout comme le produit scalaire renvoie l'échelle cos de l'angle. Vous pouvez bien sûr utiliser produit scalaire y perp point produit ensemble pour déterminer l'angle entre deux vecteurs.

Ici est un post sur ce sujet et aquí est l'article de Wolfram Math World.

10voto

Bram Points 617

Une opération vectorielle 2D utile est un produit en croix qui renvoie un scalaire. Je l'utilise pour voir si deux arêtes successives d'un polygone se plient à gauche ou à droite.

De la Chipmunk2D source :

/// 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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X