CODINGAMSLIVE ★ AMSLIVE n°7 - BRESEN MAD 1/2 ★

AMSLIVE n°07 - 3DCoding Amslive

Ca vous dirait de comprendre comment un même algo permet de tracer des lignes, appliquer zoom et rotation à un dessin, jouer un son à différentes hauteurs, justifier du texte, entre autres ? Si oui, suivez ceux qui lisent en lisant ce qui suit.

Cet algo, découvert par BRESENHAM, RAINBIRD vous l'a présenté dans AMSLIVE 2. Mais vu le nombre d'adaptations CPCiennes de DOOM reçues à la rédaction, j'en ai déduit que personne n'avait su le manipuler. Plutôt que de l'expliquer, je vais vous montrer COMMENT LE TROUVER ! Vous saisirez alors mieux le principe et n'aurez pas à apprendre l'algo par coeur : en resuivant le raisonnement, vous l'obtiendrez sans peine sur votre petit cahier de brouillon.

ZE ALCO DE LIGNE

C'était lors du ZE MEETING '96. Il me semble que j'étais en short. A moins que non. Je cherchais la façon la plus rapide d'afficher une ligne (la commande DRAW du système est bien conçue mais inadaptée à l'animation d'une cafetière en 3D). Déjà, imaginez le problème : si on affiche un point à droite du précédent, on obtient une ligne droite. Si c'est en haut à droite, on obtient une ligne à 45°.


–Schéma 1 –

Comment avoir les pentes intermédiaires ? ZIK me conseilla de me pencher sur le coefficient directeur. J'acquiesçais distraitement, perdu dans mes songes ou recouvert par les voiles translucides du sommeil. Mais, damned, je devais constater un peu plus tard qu'il avait raison. Quelle déception pour un mégalomane de ne trouver d'autres solutions que celle qui lui avait été soufflée.

COEFFICIENT DIRECTEUR

Petits souvenirs du collège. Je ne parle pas des cigarettes fumées dans les toilettes et autres coups fumants qui vous valaient irrémédiablement 3 heures de colle. Dans un repère, une ligne non parrallèle à l'axe des ordonnées peut se décrire avec une équation de la forme Y = M*X + P

M est le coefficient directeur. Si cette ligne passe par le centre du O repère, P est nul. Quelque soit la valeur de X, multipliez la par M pour obtenir l'ordonnée Y correspondante.


–Schéma 2 –

Nos 2 premiers exemples correspondaient à des lignes avec coefficients valant 0 et 1 respectivement. Le problème se résume à l'utilisation de coefficients non entiers.

DU REPERE A L'ECRAN

Tout cela est bien joli, mais il nous faut passer de notre repère sur papier à l'affichage sur

l'écran. Pour cela, on va quadriller le repère, et chaque case formée représentera un pixel a l'écran.

J'ai choisi arbitrairement de placer le quadrillage de telle sorte que les centres des cases correspondent à des points de coordonnées entières. Autrement dit, soit P entier, si un point du repère a une coordonnée comprise entre P - 0.5 et P + 0.5, il sera associé au pixel P. Vous aurez tous remarqué qu'il s'agit en fait d'un arrondi au plus proche (commande CINT du BASIC). Exemple, le point (0.6 ; 2.2) est dans le pixel (1 ; 2). Attention, ma numération part du pixel (0 ; 0) et va de 1 en 1. Pour obtenir les coordonnées en BASIC, il faut encore faire une transformation qui dépendra du mode.


–Schéma 3 –

On va travailler en mode 1 car c'est le seul où les pixels sont "aussi hauts que larges".

UN EXEMPLE DE DROITURE

Allez, traçons un segment en BASIC.

FOR X-0 TO 100:PLOT X*2,1/3*X*2:NEXT

La multiplication par 2 est la fameuse transformation dont je vous parlais plus haut. On l'isolera toujours, car cette dernière manipulation concerne l'affichage du point et non le calcul des coordonnées.

Notre but sera de transformer le programme de façon à pouvoir le traduire simplement en assembleur. Première étape, faire disparaître la multiplication. Rien de plus simple, puisque quand X est incrémenté, 1/3*X augmente de 1/3.

M = 1/3:X=0:Y=0:FOR T=0 TO 100:PLOT X*2,Y*2:Y=Y+M:X=X+1:NEXT

Je ne vous cache pas qu'il serait vraiment intéressant de ne travailler qu'avec des entiers. C'est pourquoi on va donner cette caractéristique à X et Y, quitte à travailler pour l'instant avec une variable auxiliaire qui elle n'est pas entière.

M = 1/3:X = 0:YR = 0:FOR T = 0 TO 100: Y=CINT (YR) : PLOT X*2 ,Y*2 :YR =YR +M:X=X+1:NEXT

Cela parait plus compliqué, mais ça va très bien se goupiller pour nous.

SUS AU CINT

D'arrondir au plus proche (CINT) est moins facile que d'arrondir par défaut (INT). Ce dernier cas consiste à simplement se débarrasser de ce qu'il y a après la virgule. Or, tout nombre dont la partie décimale est plus grande que 0,5 se verra arrondi à l'entier supérieur par CINT. En ajoutant 0.5 à ce nombre, et en arrondissant par INT, on obtient le même résultat. Si la partie décimale est plus petite que 0.5, en ajoutant 0.5, la partie entière sera inchangée. Ceci n'était pas vraiment une démonstration, mais vous pouvez faire confiance à tonton MADRAM : quelque soit A, CINT (A) = INT (A+0.5) D'où la nouvelle version du programme :

M-1/3 :X=0:YR=0.5:FOR T = 0 TO 100 :Y = INT (YR) : PLOT X*2 , Y*2 : YR = YR + M :X = X+1 :NEXT

Suivons l'évolution des variables YR et Y :

YR ; Y
0.5 ;0
0.833... ; 0
1.166... ; 1
1.5 ;1
1.833... ; 1
2.166... ; 2
...

Y est incrémenté à chaque changement de la partie entière YR. Pour détecter ce changement, on va tester si YR dépasse 1. Puis, pour ne pas avoir à tester s'il dépasse 2, on le décrémentera, en nous fiant à l'identité des inégalités YR > 2 et YR-1 > 1.

10 M = 1/3:X=0:Y=0:YR=0.5:FOR T=0 TO 100:PLOT X*2,Y*2:YR=YR+M
20 IF YR>=1 THEN YR=YR-1 :Y=Y+1
30 X=X+1:NEXT

Les premières valeurs prises par YR seront 0.5,0.833,0.166,0.5...

UNE REMARQUE AU PASSAGE

La seule contrainte qu'on se soit fixée est d'éliminer les lignes verticales dont le coefficient directeur serait infini. Mais celui-ci peut tout à fait être supérieur à 1. Pourtant, dans la plupart des cours sur BRESENHAM, on vous dira que non. Pourquoi ?!?

Parce que dans l'astuce qui consiste à décrémenter YR pour le ramener entre 0 et 1, on considérait qu'il était compris entre 1 et 2. Mais si M est plus grand que 1, ce ne sera pas forcément le cas. Pour rendre l'algo plus universel, il faut refaire un test après la décrémentation.

A l'étape à laquelle en est notre programme, cela revient à rajouter un GOTO 20 à la fin de la ligne 20. Ceci ne résous pas un problème, à savoir que la ligne est tracée en pointillé (toujours dans le cas M > 1). A chaque valeur de X un seul point est affiché. Un PLOT X*2,Y*2 placé avant Y=Y+1 est le remède.

Aux perfectionnistes qui reprocheront que 2 points puissent être affichés au même endroit, j'offre cette ligne :

15 IF YR>=1 THEN YR=YR-1:Y=Y+1 ELSE 30

Sachez enfin qu'il est possible d'obtenir un algo unique de tracé de ligne, quelque soit l'orientation de cette dernière. Mais il est un peu lourd, notamment à cause des tests de fin de ligne.

AMSLIVE n°7

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

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 149 millisecondes et consultée 1704 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.