Il nous reste à aborder le passage de la 3D à la 2D (pour nos “simple” écrans)…
Nous avons transformé des points (qui peuvent former des objets) dans un espace à 3 dimensions, avec un point remarquable (0,0,0) qui est le centre de l'univers cartésiens ainsi décrit.
Par défaut, si l'on applique les formules de projection ci-dessous, l'observateur sera un point “remarquable” (et immobile) situé en (0,0,0) et qui regarderait vers le fond (0°,0°,0°) … :D
Si l'on désire représenter un point 3D en 2D, après transformation(s), on peut simplement ignorer la coordonnées 'Z'
Sachant qu'un écran informatique peut afficher des points de 0,0 à sizex, sizey et que les valeurs de x' et y' peuvent quand à elles varier t entre -∞ et +∞, il convient de centrer le 0,0 sur l'écran et d'éliminer les valeurs “hors écran”
x_screen = x_transformed - (sizex/2); y_screen = y_transformed - (sizey/2) ; if ((x_screen>=0) and (x_screen<sizex) and (y_screen>=0) and (y_screen<sizey)) draw_pixel(x_screen,y_screen,1);
Si l'on désire représenter un point 3D en 2D, après transformation(s), on simuler l'éloignement (par rapport à l'observateur) en faisant un rapport sur la valeur z, après transformation:
Cette projection transforme un point 3D en 2D en tenant compte de l'éloignement, plus le Z est grand, plus les points projetés se “rapprochent” les un des autres autour du 0,0, et donc donneront l’illusion d’être “plus loin”.
C'est la technique qui est utilisée en peinture (technique du “point de fuite”) pour donner un sentiment de “profondeur” à l'image, on parle alors de perspective.
Dans cette projection, Il convient toutefois de prendre en compte le risque d'avoir un z nulle avant d'appliquer la projection.
On peut soit ignorer les points qui sont sur l'origine, soit les afficher en utilisant la projection du fainéant, je conseille de quand même les afficher.
if (z_screen==0) { x_screen = x_screen; y_screen = y_screen; } else { x_screen = x_screen / z_screen; y_screen = y_screen / z_screen; }
Cette gestion ne vous empêches pas de quand même centrer votre 0,0 et les “hors-écran”, donc alourdis un peu la projection.
Considérons un instant l'écran (de projection) comme pouvant se situé entre l'observateur et l'objet observé, il convient de prendre en compte cette différence, afin notamment de gérer l'effet de focale (et éventuellement de traiter le centrage)…
la projection sera dès lors calculée avec les formules suivantes
Si l'on considère que ex = -(sizex/2) et ey = -(sizey/2), et que ez=1, alors nous retombons sur la formule de la projection du pauvre… qui tiens nativement compte du centrage de l'écran…
Dans les projections précédentes, nous avons toujours fait bouger les points de l'univers autours du 0,0,0 et non fait bouger un observateur dans cet univers, la logique voudrait que ce soit en effet l'observateur qui se déplace et non l'univers.
Si l'on désire faire entrer la notion d'observateur(caméra)/point de vue, il convient d'inclure ce point (et là ou il regarde) dans les calculs de transformation/projection et d'appliquer aux points de l'univers une transformation spéciale.
Si l'on désire appliquer les transformations en prenant en compte la position de l'observateur, il convient d'appliquer la transformation de la caméra, cette transformation inclu une rotation autour de l'axe Z, de l'axe Y et de l'axe X de chaque point par rapport à la position de l'observateur/caméra et à son orientation (du regard).
x,y,z : coordonnées cartésienne du point a transformer
ox,oy,oz : coordonnées cartésienne, position de l'oeil dans l'espace.
ax,ay,az : angles de vue , ces angles définissent la direction du regard à partir du point de l'observateur (ox,oy,oz).
Alors la matrice de transformation devient
Dans l'introduction à la projection, j'ai évoqué l'observateur comme étant un point remarquable du système localisé en (0,0,0), et ayant une direction de regard a angle nul (0°,0°,0°)
Si l'on n'a pas d'angle de vue (ax=ay=az=0), les matrices de rotation deviennent des matrices “unités” (car (sin(0)=0 et cos(0)=1), et l'on peut dès lors simplifier le produit en “translation”:
Mais il ne faut pas oublié que l'observateur est le 0,0,0; ce qui veut dire que ox=oy=oz=0, alors
Et l'on retombe bien sur une matrice toute simple.
Il est impossible de conclure simplement, mais je vais tenter de résumer au mieux tout ce qui a été vu, et de fournir une matrice/formule simple
vec quelques définitions voici les formules que nous allons implémenter.
ox,oy,oz : coordonnées cartésienne, position de l'oeil dans l'espace.
w : 1 (valeur de 1 pour simplifier)
x[],y[],z[] : coordonnées cartésienne des points a transformer
ex,ey,ez : coordonnées cartésienne de l'écran avec ex=-(sizex/2), ey=-(sizey/2) et ez=1
ax,ay,az : angles de vue , ces angles définissent la direction du regard à partir du point de l'observateur (ox,oy,oz).
cx = cos(ax), sx = sin(ax), cy = cos(ay), …
nx,ny,,nz : coordonnées cartésienne, position temporaire de calcul
pseudo code:
foreach { dx = x[]-ox dy = y[]-oy dz = z[]-oz nx = cy*(sz*dy + cz*dx) - sy*dz ny = sx*(cy*dz + sy*(sz*dy + cz*dx)) + cx*(cz*dy - sz*dx) nz = cx*(cy*dz + sy*(sz*dy + cz*dx)) - sx*(cz*dy - sz*dx) x' = nx*(ez/nz) + ex y' = ny*(ez/nz) + ey }
3D et vrai Relief
J.J.Meyer
ISBN: 2-7091-0990-5
https://www.amazon.co.uk/3D-vrai-relief-images-synthese/dp/2709109905
https://archive.org/details/3-d-et-vrai-relief-images-de-syntheseacme-rare/mode/2up
PC Interdit 2eme édition Windows 95 & Jeux 3D
Boris Bertelsons, Mathias Rasch et Jan Erik Hoffmann
ISBN: 2-7429-0500-6
https://www.amazon.fr/PC-interdit-Collectif/dp/2742905006
https://archive.org/details/pcinterdit0000bert/page/n6/mode/2up
Mathematics of 3D Graphics
Juan David Gonzalez Cobas
Universidad de Oviedo
Blender Conference 2004
https://www.cs.trinity.edu/~jhowland/class.files.cs357.html/blender/blender-stuff/m3d.pdf
https://en.wikipedia.org/wiki/3D_projection
https://fr.wikipedia.org/wiki/Projection_affine
https://fr.wikipedia.org/wiki/Perspective_axonom%C3%A9trique