04 — Transformer points et vecteurs
Ce que tu vas apprendre
- Pourquoi une matrice 3×3 ne peut pas translater, et comment la 4×4 résout ça
- Les coordonnées homogènes et la fameuse composante
w - Pourquoi un point subit la translation mais pas un vecteur
- Quand et pourquoi diviser par
w
Prérequis
- Les matrices et la distinction point / vecteur
On a dit qu'une matrice transforme un point ou un vecteur. Mais il y a un hic : une matrice 3×3 sait tourner et redimensionner, pas déplacer. Or déplacer un point (le translater) est l'opération la plus banale qui soit. La solution est une petite astuce élégante : les coordonnées homogènes.
Le problème de la translation
Multiplier (x, y, z) par une 3×3 produit toujours une combinaison linéaire des coordonnées d'origine. Quoi qu'on mette dans la matrice, on ne peut pas ajouter une constante — donc pas déplacer l'origine. La translation est exclue. Il manque un degré de liberté.
Les coordonnées homogènes
L'astuce : on ajoute une quatrième composante, w, fixée à 1 pour un point :
P = (x, y, z, 1)
Ce point « homogène » se multiplie maintenant par une matrice 4×4. La transformation d'un point s'écrit (convention vecteur-ligne de Scratchapixel, le point multiplie la matrice à gauche) :
P'.x = P.x·M₀₀ + P.y·M₁₀ + P.z·M₂₀ + 1·M₃₀
P'.y = P.x·M₀₁ + P.y·M₁₁ + P.z·M₂₁ + 1·M₃₁
P'.z = P.x·M₀₂ + P.y·M₁₂ + P.z·M₂₂ + 1·M₃₂
Regarde la dernière colonne de chaque ligne : M₃₀, M₃₁, M₃₂. Comme ils sont multipliés par le w = 1, ils s'ajoutent tels quels au résultat. C'est la translation. La quatrième ligne de la matrice stocke le déplacement. Le degré de liberté manquant est retrouvé.
| rotation + échelle 0 |
M = | (bloc 3×3) 0 |
| 0 |
| Tx Ty Tz 1 | ← la 4ᵉ ligne = translation
Pourquoi 4×4 et pas 4×3 ?
Techniquement, une matrice 4×3 suffirait pour rotation + échelle + translation. Mais on garde une 4×4 avec une quatrième colonne (0, 0, 0, 1), pour deux raisons : les développeurs préfèrent les matrices carrées (elles se multiplient et s'inversent uniformément), et surtout cette quatrième colonne devient non triviale pour la projection perspective. Là, w cesse de valoir 1, et c'est précisément ce qui crée l'effet de perspective. On garde donc la place dès maintenant.
Le point clé : point ≠ vecteur
Voici la raison profonde de distinguer points et vecteurs (article 00). Un vecteur représente une direction sans position. Le déplacer n'a aucun sens — une flèche reste la même flèche où qu'on la mette. Donc un vecteur ne doit pas subir la translation. On le transforme avec la même matrice, mais en ignorant la quatrième ligne :
V'.x = V.x·M₀₀ + V.y·M₁₀ + V.z·M₂₀
V'.y = V.x·M₀₁ + V.y·M₁₁ + V.z·M₂₁
V'.z = V.x·M₀₂ + V.y·M₁₂ + V.z·M₂₂
Concrètement, un vecteur a un w = 0 (et non 1) : la translation, multipliée par 0, disparaît. Si tu translates un vecteur direction par erreur, tes calculs de lumière et de caméra partent en vrille de façon difficile à diagnostiquer. C'est l'une des erreurs les plus fréquentes du débutant en 3D.
Diviser par w
Dans une transformation classique (rotation, échelle, translation), w' reste égal à 1 et on n'a rien à faire. Mais après une matrice de projection, w' peut valoir autre chose que 1. Il faut alors diviser x', y', z' par w' pour revenir à des coordonnées cartésiennes normales. C'est cette « division par w » (la division perspective) qui fait qu'un objet lointain apparaît plus petit. Deux stratégies de code coexistent : toujours calculer et normaliser par w', ou supposer w = 1 par défaut et n'utiliser une fonction spéciale que pour les projections.
L'article suivant attaque la convention qui détermine comment on écrit ces multiplications — vecteur-ligne ou vecteur-colonne — et pourquoi c'est la source de tant de bugs entre moteurs et API graphiques.
Sources
- Scratchapixel. Geometry — Transforming Points and Vectors. scratchapixel.com
- Sanderson, G. (3Blue1Brown). Linear transformations (et la vidéo bonus sur les coordonnées homogènes / projection). 3blue1brown.com
- Lengyel, E. (2011). Mathematics for 3D Game Programming and Computer Graphics (3ᵉ éd.), chap. 4 « Transforms ». Cengage.