La projection
Ceux qui ne s'intéressent pas aux maths peuvent très bien pomper le résultat final.
La question est : nous avons des points dans l’espace, quelle est leur position à l’écran ? Question pertinente, on affiche sur un écran, et pas dans l’espace. Nous devons passer d’un espace à trois dimensions vers un espace à deux dimensions. Une formule souvent utilisée (il en existe d’autres) est la formule suivante :
u=factor_x*x/z +w/2 v=factor_y*y/z +h/2
Avec (u,v) la coordonnée sur l’écran, et (x,y,z) la coordonnée dans l’espace. On a également w et h qui sont la longueur et la largeur en pixel de l’image projetée (souvent tout l’écran, mais ça pourrait n’être qu’une fenêtre).
Cette formule suppose que l’observateur se trouve en (0,0,0), que le plan de projection (celui où se trouve l’écran, finalement) est Z=1, que c’est écran est centré autour de l’axe des Z, et que l’observateur regarde dans la direction de l’axe des Z. Vu du haut, ça donne :
Le but ici, c’est de trouver ce que valent ces factor_x et factor_y. On va travailler avec une méthode appelée « l’identification » : on sait à quel résultat on doit arriver, et on va faire en sorte que factor_x et factor_y nous amènent effectivement à ce résultat.
Quel est le résultat auquel nous voulons arriver ? Nous voulons qu’un point de l’espace qui se trouve sur un plan qui correspond aux angles d’ouverture de la caméra (et donc aux limites de visibilité) se trouve sur le bord de l’écran. Précisons donc nos hypothèses :
Il y a quatre plans qui permettent de délimiter la zone visible, deux plans verticaux et deux plans horizontaux, on suppose que les plans verticaux forment un angle 2ax entre eux et font un angle ax avec l’axe des Z.
Les deux plans horizontaux font un angle 2ay entre eux, et font un angle ay avec l’axe des Z.
Le plan de projection est Z=1. On pourrait tout refaire en considérant cette valeur comme paramétrique, mais ça n’apporte fondamentalement pas grand chose si ce n’est des problèmes dans les algorithmes de correction de perspective...
On appelle souvent « ratio » le rapport tan(ax)/tan(ay). Il est fréquent qu’au lieu de configurer le viewport avec un angle horizontal et un angle vertical, on demande un angle horizontal et un ratio. Un bon ratio est évidemment un ratio qui fait en sorte que l’écran sur lequel vous projetez à le même rapport de dimensions que la taille (en mètres, sisi) de l’image finale que vous, utilisateur, verrez sur l’écran. Bref, si vous affichez en plein écran avec une résolution de 640x480 et que vous supposez qu’un pixel est carré (ce qui est vrai en 640x480, mais pas en 640x400), le ratio est de 640/480=4/3. En pratique si on suppose toujours qu’un pixel est à peu près carré, le ratio se calcule comme le rapport de la longueur par la largeur de l’image affichée. Une résolution d’écran a des pixels carrés si les proportions de l’image sont égales aux proportions du nombre de pixel. Un écran est normalement en proportions 4/3, donc il faut travailler dans des résolutions qui respectent ce rapport : (320x240), (400x300), (512x384), (640x480), (800x600), (1024x768), (1152x864), (1600x1200), mais PAS (320x200), (640x400) , (1280x1024), et autres bizarreries.
Bref : ratio=w/h (sinon on va encore dire que je complique tout)
Un point se trouvant à l’intersection du plan vertical de droite avec le plan horizontal du bas est (tan(ax),tan(ay),1). On veut que sa projection donne (w,h), c’est à dire le coin inférieur droit de l’écran.
Il faut donc que:
w=factor_x*tan(ax)+w/2 h=factor_y*tan(ay)+h/2
Donc que:
w/(2*tan(ax))=factor_x h/(2*tan(ay))=factor_y
Et c’est gagné. Comme on voit que factor_x et factor_y ne dépendent que de la résolution et des angles du viewport, il suffit de les calculer une seule fois au moment où ces valeurs changent, et basta.
En résumé :
u=factor_x*x/z +w/2 v=factor_y*y/z +h/2
avec
factor_x=w/(2*tan(ax)) factor_y=h/(2*tan(ay))
On voit que plus ax et ay sont petits, et plus le facteur est grand, et donc plus l’image projetée sera grande. C’est normal, vu que diminuer l’angle d’ouverture d’une caméra, c’est justement la définition du zoom.