Supposons que vous écrivez du code matriciel qui gère la rotation, la traduction, etc. pour l'espace 3D.
Maintenant, les matrices de transformation doivent être 4x4 pour s'adapter au composant de traduction.
Cependant, vous n'avez pas vraiment besoin de stocker un w
composant dans le vecteur , n'est-ce pas ?
Même dans la division en perspective, vous pouvez simplement calculer et stocker en w
dehors du vecteur et diviser en perspective avant de revenir de la méthode.
Par exemple:
// post multiply vec2=matrix*vector
Vector operator*( const Matrix & a, const Vector& v )
{
Vector r ;
// do matrix mult
r.x = a._11*v.x + a._12*v.y ...
real w = a._41*v.x + a._42*v.y ...
// perspective divide
r /= w ;
return r ;
}
Est-il utile de stocker w
dans la classe Vector?
mathematics
vector
projection
bobobobo
la source
la source
r.x = ... + a._14*v.w;
r.y = ... + a._24*v.w;
r.z = ... + a._34*v.w;
r.w = ... + a._44*v.w;
regardez ma réponse pour plus de détailsRéponses:
EDIT Avertissement : Pour plus de commodité dans cette réponse, les vecteurs avec w == 0 sont appelés vecteurs et avec w == 1 sont appelés points. Bien que, comme l'a souligné FxIII, ce n'est pas une terminologie mathématiquement correcte. Cependant, puisque le point de la réponse n'est pas la terminologie, mais la nécessité de distinguer les deux types de vecteurs, je m'en tiendrai. Pour des raisons pratiques, cette convention est largement utilisée dans le développement de jeux.
Il n'est pas possible de faire la distinction entre les vecteurs et les points sans composante «w». C'est 1 pour les points et 0 pour les vecteurs.
Si les vecteurs sont multipliés avec une matrice de transformation affine 4x4 qui a une traduction dans sa dernière ligne / colonne, le vecteur serait également traduit, ce qui est faux, seuls les points doivent être traduits. Le zéro dans la composante «w» d'un vecteur s'en occupe.
La mise en évidence de cette partie de la multiplication matrice-vecteur le rend plus clair:
C'est-à-dire qu'il serait faux de traduire un vecteur, par exemple un axe de rotation, le résultat est tout simplement faux, En ayant son 4ème composant zéro, vous pouvez toujours utiliser la même matrice qui transforme les points pour transformer l'axe de rotation et le résultat sera valide et sa longueur est conservée tant qu'il n'y a pas d'échelle dans la matrice. C'est le comportement que vous souhaitez pour les vecteurs. Sans le 4ème composant, vous devriez créer 2 matrices (ou 2 fonctions de multiplication différentes avec un 4ème paramètre implicite. Et faire 2 appels de fonction différents pour les points et les vecteurs.
Pour utiliser les registres vectoriels des processeurs modernes (SSE, Altivec, SPU), vous devez quand même passer 4x flottants 32 bits (c'est un registre 128 bits), plus vous devez vous occuper de l'alignement, généralement 16 octets. Vous n'avez donc pas la possibilité de sécuriser l'espace pour le 4ème composant de toute façon.
EDIT: La réponse à la question est essentiellement
Il faut en choisir une, il n'est pas possible de ne stocker que {x, y, z} et de n'utiliser qu'une seule fonction de multiplication matrice-vecteur. XNA par exemple utilise cette dernière approche en ayant 2 fonctions Transform dans sa classe Vector3 , appelées
Transform
etTransformNormal
Voici un exemple de code qui montre les deux approches et démontre la nécessité de distinguer les deux types de vecteurs de 1 des 2 façons possibles. Nous déplacerons une entité de jeu avec une position et une direction de regard dans le monde en la transformant avec une matrice. Si nous n'utilisons pas le composant «w», nous ne pouvons plus utiliser la même multiplication matrice-vecteur, comme le montre cet exemple. Si nous le faisons de toute façon, nous obtiendrons une mauvaise réponse pour le
look_dir
vecteur transformé :État initial de l'entité:
Maintenant, une transformation avec une translation de x + 5 et une rotation de 90 degrés autour de l'axe y sera appliquée à cette entité. La bonne réponse après la transformation est:
Nous n'obtiendrons la bonne réponse que si nous distinguons les vecteurs avec w == 0 et les positions avec w == 1 de l'une des manières présentées ci-dessus.
la source
Si vous créez une classe Vector, je suppose que la classe stockera la description d'un vecteur 3D. Les vecteurs 3D ont des magnitudes x, y et z. Donc, à moins que votre vecteur ait besoin d'une amplitude w arbitraire, non, vous ne le stockerez pas dans la classe.
Il y a une grande différence entre un vecteur et une matrice de transformation. Étant donné que DirectX et OpenGL traitent des matrices pour vous, je ne stocke généralement pas de matrice 4x4 dans mon code; je stocke plutôt des rotations d'Euler (ou des Quaternions si vous le souhaitez - qui ont par hasard un composant aw) et une traduction x, y, z. La translation est un vecteur si vous le souhaitez, et la rotation s'inscrirait techniquement dans un vecteur également, où chaque composant stockerait la quantité de rotation autour de son axe.
Si vous voulez plonger un peu plus profondément dans les mathématiques d'un vecteur, un vecteur euclidien n'est qu'une direction et une magnitude. Donc, typiquement, cela est représenté par un triplet de nombres, où chaque nombre est la grandeur le long d'un axe; sa direction est impliquée par la combinaison de ces trois grandeurs, et la grandeur peut être trouvée avec la formule de distance euclidienne . Ou, parfois, il est vraiment stocké sous la forme d'une direction (un vecteur de longueur = 1) et d'une amplitude (un flottant), si c'est ce qui convient (par exemple, si l'amplitude change plus souvent que la direction, il peut être plus pratique de simplement changer ce nombre de grandeur que pour prendre un vecteur, le normaliser et multiplier les composantes par la nouvelle grandeur).
la source
La quatrième dimension du vecteur 3D est utilisée pour calculer les transformations affines qui seront impossibles à calculer en utilisant uniquement des matrices. L'espace reste tridimensionnel, ce qui signifie que le quatrième est cartographié dans l'espace 3D d'une manière ou d'une autre.
Mapper une dimension signifie que différents vecteurs 4D indiquent le même point 3D. La carte est que si A = [x ', y', z'.w '] et B = [x ", y", z ", w"] ils représentent le même point si x' / x "= y ' / y "= z '/ z" = w' / w "= α c'est-à-dire que les composantes sont proportionnelles pour le même coefficient α.
Dit que vous pouvez exprimer un point - disons (1,3,7) - de manières infinies comme (1,3,7,1) ou (2,6,14,2) ou (131,393,917,131) ou en général (α · 1, α · 3, α · 7, α).
Cela signifie que vous pouvez mettre à l'échelle un vecteur 4D à un autre représentant le même point 3D de sorte que w = 1: la forme (x, y, z, 1) est la forme canonique.
Lorsque vous appliquez une matrice à ce vecteur, vous pouvez obtenir un vecteur qui n'a pas le w = 1, mais vous pouvez toujours mettre à l'échelle les résultats pour le stocker sous forme canonique. La réponse semble donc être "vous devez utiliser des vecteurs 4D lorsque vous faites des calculs mais ne stockez pas le quatrième composant" .
C'est tout à fait vrai, mais il y a certains points que vous ne pouvez pas mettre sous forme canonique: des points comme (4,2,5,0). Ces points sont spéciaux, ils représentent un point infini dirigé et peuvent être normalisés en vecteur unité de manière cohérente: vous pouvez aller en toute sécurité à l'infini et revenir (même deux fois) sans être Chuck Norris. Vous obtiendrez une misérable division par zéro si vous essayez de forcer ces vecteurs sous forme canonique.
Maintenant que vous savez, le choix vous appartient!
la source
Oui. Votre transformation est incorrecte pour certains types de vecteur. Vous pouvez le voir dans la bibliothèque mathématique D3DX - ils ont deux fonctions de multiplication matrice-vecteur différentes, une pour w = 0 et une pour w = 1.
la source
Cela dépend de ce que vous voulez et de ce dont vous avez besoin. :)
Je le stockerais, b / c c'est nécessaire pour les transformations et autres (vous ne pouvez pas multiplier un vecteur 3 avec une matrice 4x4), mais si vous avez toujours juste un aw de 1, je suppose que vous pouvez simplement le simuler.
la source