CODINGAMSLIVE ★ AMSLIVE n°14 - 3D EST-CE L'AMOUR ? ★

AMSLIVE n°14 - 3D est-ce l'amour ?Coding Amslive

Encore un article assez matheux dans ce numéro. Que voulez-vous, je ne peux pas faire d'omelettes sans vous cassez les œufs. Mon but n'est pas de vous donner les routines toutes faites (NDSNN : Eh m... ! Moi qui pensais que ce serait ENFIN un article compréhensible !), mais au contraire de vous décortiquer les méthodes employées afin que vous compreniez comment ça marche et puissiez optimiser vous-mêmes les dites méthodes, voire en trouver d'autres. Respiration.

Reprenons là où nous en étions. (NDSNN : Ah ? On avait déjà parlé de 3D ? Il faudrait que je les lise, les Amstrad Live que je maquette.)
La distance de l'écran de projection par rapport à P (le point de vue) importe peu, du moment qu'elle n'est pas nulle. C'est l'ouverture qui compte, ensuite, la proportionnalité fait son œuvre. Le champ de vision se résume à une pyramide, plus ou moins aplatie suivant l'angle d'ouverture justement. Les différents écrans de projection équivalents correspondent aux bases possibles de cette pyramide.

CALCULS FRENETIQUES

Celui-là il est pas évident ! Je vous le donne, parce que sinon quasiment personne ne l'aurait vu (moi-même ne l'ai pas retrouvé tout de suite), et du coup mon décarcassement aurait été aussi inutile et
vain qu'une caresse donnée au vent. Frénétique : délirant, effréné, etc, mais aussi contrepet de néphrétique. Néphrétique : relatif au rein malade (présence de calculs le plus souvent).

Je vais essayer de bien détailler les calculs, pour ceux qui auraient séché les cours de maths pour aller jouer au baby-foot avec One.

Les coordonnées (u';v';w') du projeté d'un point A (u;v;w), sont celles de l'intersection entre la droite (PA) et le plan de projection. Si on appelle PVx, PVy, PVz les coordonnées du point de vue, et ECx, ECy, ECz celles du centre de l'écran, les équations respectives sont :

. 0<t<1 x = u + t*(PVx - u)
y = v + t*(PVy - v)
;z = w + t*(PVz - w)

. (PVx-ECx)*(x-ECx) + (PVy-ECy)*(y-ECy) + (PVz-ECz)*(z-ECz) = 0

Dans cette égalité, on remplace x, y, et z par les expressions précédentes pour trouver :

PVx-ECx)^2 + (PVy-ECy)^2 + (PVz-ECz)^2
t = -------------------------------------------------------------
(ECx-PVx)*(u-PVx)+(ECyPVy)*(v-PVy)+(ECz-PVz)*(w-PVz)

En introduisant (après lubrification) cette valeur de t dans les premières égalités on obtient u' v' w'. Vous commencez à regretter l'article sur la multiplication ?! Dans le prog BASIC, ces calculs se retrouvent dans la ligne 30100 (le numérateur reste le même pour tous les points) et dans le sous-programme en 10000.

REPERE COMME UN BLEU

L'écran de projection représente l'écran du CPC, rappelez-vous (si vous ne faites pas d'effort, mes articles ne feront pas d'effet). Le repère formé par les vecteurs i(ix,iy,iz) et j(jx,jy,jz) correspond donc à un repère de l'écran. (Désolé je ne peux pas utiliser les petites flèches pour les vecteurs. Faites doublement attention pour différencier vecteurs, points et longueurs)

Par conséquent, si on arrive à déterminer R et S tel que

(u',v',w') = R * (ix,iy,iz) + S * (jx,jy,jz) + (ECx,ECy,ECz)

on aura tout bonnement trouvé nos coordonnées 2D. Pour résoudre cette équation, on utilise ce qu'on appelle, dans le jargon mathématicalistique, le produit scalaire (lignes 20000 et 20010 du prog basic).

R' = ix*(u'-ECx) + iy*(v'-ECy) + iz*(w'-ECz)
S' = jx*(u'-ECx) + jy*(v'-ECy) + jz*(w'-ECz)

pour la petite histoire, R=K*R' et S=K*R' où K est une constante dont on se fout éperdument. Ce qui nous intéresse, c'est d'obtenir les coordonnées avec les unités de l'écran directement. Pour cela, on va arranger le repère (i,j). Le point de vue, le centre de l'écran et l'angle d'ouverture une fois définis, on en déduit M le milieu du côté droit de l'écran.

Quand le vecteur i est parallèle à l'axe Ox, il est de la forme (3,0,0). Dans ce cas R'(M), le produit scalaire appliqué au vecteur EM, se résume au produit a*(Mx-ECx). Raisonnons en distances maintenant. Nous avons vu que la plan de projection pouvait être placé à n'importe quelle distance non nulle du point de vue. Faisons alors de sorte que la distance entre E et P soit 1. Du coup, Mx-ECx = EM = tan (ouv).

Or, M étant à l'extrême droite de l'écran, on est en droit de souhaiter que R'(M) retourne l'abscisse maximum, +320 dans un mode graphique normal.
Tout ça pour en déduire une valeur de a, et par extension, la longueur de nos vecteurs i et j. Reste à trouver leurs orientations.

SINUS OU SA ROBE

(NDSNN : Contrairement à ce qu'on pourrait croire, Amstrad Live n'est absolument pas favorable à la consommation de substances illicites) Non seulement i et j sont perpendiculaires entre eux, mais chacun doit être perpendiculaire à l'orientation du champ de vision, qui est déterminé par les points P (PV dans le prog) et E (EC).
J'ai décidé d'exprimer cette orientation en coordonnées sphériques, qui permet des déplacements de caméra beaucoup plus intuitifs.

Quand l'angle de dévers est nul, i est calculé de façon à être parallèle au "sol" (le plan Oxz).

Ca fait beaucoup de sinus à manipuler, et c'est assez pénible. Mais il faut savoir maîtriser ce genre de calculs, indispensables dès qu'il y a rotation.
Normalement, le point de vue est indépendant de l'orientation du champ. Le traitement effectué en 35000 permet cependant de faire tourner la caméra autour de l'objet plutôt que sur elle même. Pour déterminer i (cf lignes à partir de 30000), on fait subir au vecteur (320/tan(ouv),0,0) les rotations successives : site, azimut, dévers. Idem pour j, qui lui est au départ de la forme (0,320/tan(ouv),0). Note : on peut aussi le retrouver grâce à un produit vectoriel. Dingue, non ?

LES LACUNES DU BLEU

Ce programme, souffre de nombreux défauts :

  • La gestion de quelques touches manque, mais vous compléterez aisément.
  • Les mêmes points sur calculés plusieurs fois. Ce n'est définitivement pas la bonne façon de faire. Il faudrait d'un côté déclarer tous les points différents utilisés, et de l'autre côté définir les objets en utilisant le numéro d'un point et non plus ses coordonées. Une telle gestion a déjà été expliquée dans QUASAR 13, et je ne voulais pas alourdir.
  • Les variables sont réelles (au sens BASIC du terme), et il faudra encore faire pas mal de transformations avant de pouvoir le transcrire en assembleur.

ELARGIR L'HORIZON

Simple remarque avant de vous quitter : dans certains traités sur la perspective, vous trouverez peut-être des histoires d'horizon, de plan de terre, de points de fuite, etc.. On pourrait y voir la définition d'un nouveau type de projection, mais on peut aussi dire que ça découle d'un type de projection !
Il s'agit, en définitive, de trucs de construction géométrique, et l'application de quelques théorèmes redonnerait l'équivalent algébrique des transformations effectuées.

ALTERNATION

Pour la première fois dans l'histoire de mon quartier, une série d'articles va aller par simplicité croissante. En effet, la méthode présentée ici (dans des conditions de travail en complète contradiction avec les plus élémentaires droits de l'homme, notons pour ma défense) nécessite 12 multiplications et une division par point. J'en vois qui pouffent. Alors, next time, grand nettoyage d'été, des t, et de tout ce que vous voudrez.

Madram, houhou !

NON ! N'AYEZ PAS PEUR DETOURNER LA PAGE ! ALLEZ ! UN PEU DE CRAN ! SOYEZ FORT ! OUI, VOUS Y ETES PRESQUE ! UN DERNIER PETIT EFFORT !

10 MODE 1:PRINT"3d (Projection de centre quelconque)":PRINT"Amslive 13 Madram 5/99"
PRINT"Touches :":PRINT CHR$(240);" ";CHR$(243);" : rotation du champ de vision":PRINT"f7 et f9 : ouverture du champ"
20 '(PVx, PVy, PVz) : point de vue
21 '(ECx, ECy, ECz) : centre de l'écran
22 'ouv : angle d'ouverture
23 '(ix, iy, iz) : vecteur repère i
24 '(jx, jy, jz) : vecteur repère j
25 'azi, sit, dev : angle d'azimut, de site et de devers
26 'larg : largeur de fenêtre d'affichage
27 'dist : distance a l'origine du point de vue
30 DEG:ouv=30:azl=0:sit=0:dev=0:larg=200:dist=30:GOSUB 35000
40 DIM obj(20,2)
50 ORIGIN 320,100,320-larg,320+larg,0,200
60 INK 2,0
100 RESTORE 65000:READ A$:n=0
110 WHILE UPPER$(a$)<>"FIN":obj(n,0)=VAL(a$):READ obj(n,1):READ obj(n,2):READ a$:n=n+1:WEND
120 nbr=n
1000 GOSUB 5000
1010 '
1020 IF NOT(INKEY(1)) THEN azi=azi+10:GOSUB 35000:GOTO 1500
1040 IF NOT(INKEY(7)) THEN dev=dev+10:GOTO 1500
1060 IF NOT(INKEY(0)) THEN sit=sit+10:GOSUB 35000:GOTO 1500
1080 IF NOT(INKEY(3)) AND ouv

1090 IF NOT(INKEY(10)) AND ouv>5 THEN ouv=ouv-5:GOTO 1500
1400 GOTO 1010
1500 GOSUB 5000:GOTO 1010
1999 END

5000 CLG 2:GOSUB 30000
5010 x=obj(0,0):y=obj(0,1):z=obj(0,2):GOSUB 10000:GOSUB 20000:MOVE xp,yp,1:FOR n=1 TO nbr-1:x=obj(n,0):y=obj(n,1): z=obj(n,2):GOSUB 10000:GOSUB 20000:DRAW xp,yp:NEXT
5020 RETURN
10000 'Projection
10010 t=con/((ECx-PVx)*(x-PVx)+(ECy-PVy)*(y-PVy)+(ECz-PVz)*(z-PVz))
10020 x=t*(x-PVx)+PVx
10030 y=t*(y-PVy)+PVy
10040 z=t*(z-PVz)+PVz
10050 RETURN
20000 'Coordonnées dans nouveau repère
20010 xp=(x-ECx)*ix+(y-ECy)*iy+(z-ECz)*iz
20020 yp=(x-ECx)*jx+(y-ECy)*jy+(z-ECz)*jz
20030 RETURN
30000 'Calcul du repère de l'écran
30010 ix=(COS(dev)*COS(azi)-SIN(dev)*SIN(sit)*SIN(azi))*larg/TAN(ouv)
30020 iy=SIN(dev)*COS(sit)*larg/TAN(ouv)
30030 iz=(COS(dev)*SIN(azi)+SIN(dev)*SIN(sit)*COS(azi))*larg/TAN(ouv)
30040 jx=(-SIN(dev)*COS(azi)-COS(dev)*SIN(sit)*SIN(azi))*larg/TAN(ouv)
30050 jy=COS(dev)*COS(sit)*larg/TAN(ouv)
30060 jz=(-SIN(dev)*SIN(azi)+COS(dev)*SIN(sit)*COS(azi))*larg/TAN(ouv)
30070 ECx=PVx-COS(sit)*SIN(azi)
30080 ECy=PVy-SIN(sit)
30090 ECz=PVz+COS(sit)*COS(azi)
30100 con=(PVx-ECx)^2+(PVy-ECy)^2+(PVz-ECz)^2
30110 RETURN
35000 'Calcul point de vue
35010 PVx=COS(sit)*SIN(azi)*dist
35020 PVy=SIN(sit)*dist
35030 PVz=-COS(sit)*COS(azi)*dist
35040 RETURN
65000 DATA 0,-5,-5, 0,-5,5, -6,5,1
65010 DATA 0,-5,-5, 8,8,0, 0,-5,5,FIN
65020 DATA FIN

★ ANNÉE: ???
★ AUTEUR: MADRAM

Page précédente : AMSLIVE n°08 - 3D - BRESEN MAD

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding Src's » Wolf 3D sourcepack (Richard Wilson)
» Coding » Sdcc - 17 - 3D - Trace Points
» Coding » AMSLIVE n°02 - Balayage Video
» Coding » AMSLIVE n°16 - CRTC Detection
» Coding Src's » 3D Animated Graphics (Computing With the Amstrad)
» Coding » AMSLIVE n°01 - Balayage Video
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 534 millisecondes et consultée 2165 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.