Tracé d'un segment de droite.
Modérateur : Politburo
-
- Fonctionne à 1200 bauds
- Messages : 949
- Enregistré le : 22 sept. 2010 13:48
- Localisation : France PdD
Tracé d'un segment de droite.
J'ai une question toute bête: Comment tracer une ligne sur l'écran avec les coordonnées x1,y1 et x2,y2 de façon simple (LM ou Basic) sans faire d'opérations complexes (décimales angle etc) avec un crénelage le plus proche de la théorie ? J'ai vu des choses comme l'algorithme de Bresenham, mais la transcription en LM du 6502A risque d'etre un peu ardue ou cyclophage...
- bernouilli92
- Fonctionne à 14400 bauds
- Messages : 5266
- Enregistré le : 21 nov. 2012 13:03
- Localisation : Ile de France
Re: Tracé d'un segment de droite.
Je pense que c'est la meilleure manière, du moins la plus simple et la plus rapide.ˋ
L'algo semble compliqué avec les 8 octants mais en réalité il n'a que deux cas, quand tu fais une boucle de x1 à x2 et quand tu fais une boucle de y1 à y2.
Et à chaque itération, il faut juste savoir si on garde y ou si on incrémente y (respectivement x).
L'algo semble compliqué avec les 8 octants mais en réalité il n'a que deux cas, quand tu fais une boucle de x1 à x2 et quand tu fais une boucle de y1 à y2.
Et à chaque itération, il faut juste savoir si on garde y ou si on incrémente y (respectivement x).
HP, Casio, Sharp, Psion, quelques TI et divers autres
- gilles
- Fonctionne à 9600 bauds
- Messages : 3100
- Enregistré le : 17 avr. 2007 21:25
- Localisation : 44
- Contact :
Re: Tracé d'un segment de droite.
Il suffit de chercher du code libre sur une machine avec le meme proc, par exemple ici sur apple 2
https://github.com/nathanriggs/AppleIIA ... RBLINE.ASM
Il faudra adapter la partie qui affiche le point à l'écran et sans doute les tests de résolution. Et sans doute adapter aussi la convention pour les modes d'adressage de l'assembleur
https://github.com/nathanriggs/AppleIIA ... RBLINE.ASM
Il faudra adapter la partie qui affiche le point à l'écran et sans doute les tests de résolution. Et sans doute adapter aussi la convention pour les modes d'adressage de l'assembleur
- C.Ret
- Fonctionne à 9600 bauds
- Messages : 3419
- Enregistré le : 31 mai 2008 23:43
- Localisation : N 49°22 E 6°10
Re: Tracé d'un segment de droite.
L'Algorithme de Bresenham est une bonne méthode pour allumer les pixels de façon à suivre au mieux une droite.
Mais le principal problème des machines de l'époque du 6502A n'est pas tant de savoir quel(s) pixel(s) allumer, mais bel et bien de comment trouver le ou les bits nécessaires à cette opération dans la mémoire vidéo du machin. Et si sur les Apples de l'époque, les choses étaient assez similaires d'un modèle à l'autre et surtout bien documentées, sur d'autres systèmes ... aïe. Allumer un pixel à une position donnée de l'écran nécessite bien souvent plus de calculs ou d'astuces pour déterminer l'adresse et le(s) bit(s) à activer/désactiver que la détermination des coordonnées (x,y) à l'écran.
Si le système destination a nativement quelques capacités graphiques "haute résolution" il sera plus efficace de trouver une bonne documentation et envisager d'utiliser (au moins en partie) les sous-routines et les bouts de code dont il dispose en ROM.
S'il s'agit d'un système (comme le Commodore C64 par exemple) qui a un affichage high-resolution couleur nécessitant l'initialisation via les registres d'une puce secondaire (le VIC II) dont il faut configure les E/S et les modes d'adressage selon les bons banks (différents des bank d'adresses vu par le 65oo) et qu'il n'y a aucune ROM basic ou autre pour initialiser ou faciliter l'utilisation de l'affichage HR. Alors bon courage. Faire tout de A à Z va vite être très compliqué.
C'est pour quel système basé sur un 6502 ?
Mais le principal problème des machines de l'époque du 6502A n'est pas tant de savoir quel(s) pixel(s) allumer, mais bel et bien de comment trouver le ou les bits nécessaires à cette opération dans la mémoire vidéo du machin. Et si sur les Apples de l'époque, les choses étaient assez similaires d'un modèle à l'autre et surtout bien documentées, sur d'autres systèmes ... aïe. Allumer un pixel à une position donnée de l'écran nécessite bien souvent plus de calculs ou d'astuces pour déterminer l'adresse et le(s) bit(s) à activer/désactiver que la détermination des coordonnées (x,y) à l'écran.
Si le système destination a nativement quelques capacités graphiques "haute résolution" il sera plus efficace de trouver une bonne documentation et envisager d'utiliser (au moins en partie) les sous-routines et les bouts de code dont il dispose en ROM.
S'il s'agit d'un système (comme le Commodore C64 par exemple) qui a un affichage high-resolution couleur nécessitant l'initialisation via les registres d'une puce secondaire (le VIC II) dont il faut configure les E/S et les modes d'adressage selon les bons banks (différents des bank d'adresses vu par le 65oo) et qu'il n'y a aucune ROM basic ou autre pour initialiser ou faciliter l'utilisation de l'affichage HR. Alors bon courage. Faire tout de A à Z va vite être très compliqué.
C'est pour quel système basé sur un 6502 ?
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
-
- Fonctionne à 1200 bauds
- Messages : 949
- Enregistré le : 22 sept. 2010 13:48
- Localisation : France PdD
Re: Tracé d'un segment de droite.
En fait c'est pour l'Oric Atmos, je viens de finir mon code, il fait 600 octets environ, prends en charge toutes les directions, les sextets de la haute résolution de l'ordi et l'effacement des segments tracés (pour ne pas effacer les 8k d'écran a chaque fois).
En fait, je trouve le code de la romBasic lent et moche (un trait qui fait 100 points de long et 3 de haut devrait faire 3 "marches d'escalier" presque égales, ce que ne fait pas correctement la romBasic, j'ai fait un algorithme simplifié qui trace un segment avec le crénelage attendu. Si le tableau noir pour la prochaine convention n'a pas été démonté, je peux vous faire une démo. Si je réinvente la roue, ce nest pas grave, on passera un bon moment, si ce que je propose est nouveau, Monsieur Bresenham m'offrira une biere...
En fait, je trouve le code de la romBasic lent et moche (un trait qui fait 100 points de long et 3 de haut devrait faire 3 "marches d'escalier" presque égales, ce que ne fait pas correctement la romBasic, j'ai fait un algorithme simplifié qui trace un segment avec le crénelage attendu. Si le tableau noir pour la prochaine convention n'a pas été démonté, je peux vous faire une démo. Si je réinvente la roue, ce nest pas grave, on passera un bon moment, si ce que je propose est nouveau, Monsieur Bresenham m'offrira une biere...
Re: Tracé d'un segment de droite.
J'ai écrit ça à partir d'un algorithme que je trouve très moche trouvé sur le net mais il parait que c'est le plus efficace ... Il n'y a que des additions, soutraction et multiplication par 2. Je l'utilise pour mon programme TPSprite, donc ca marche ;D Mais ne me demandez par pourquoi, j'ai vraiment transcrit de l'algorithme vers le Pascal en mode bourrin !
Code : Tout sélectionner
Procedure DrwSpdLin(l1,c1,l2,c2:Integer; c:Byte);
Var dl,dc,e,i : Integer;
Begin
SetGraPen(c);
DrwPnt(l1,c1,c);
DrwPnt(l2,c2,c);
dl:=l2-l1;
If dl<>0 Then Begin
If dl>0 Then Begin
dc:=c2-c1;
If dc<>0 Then Begin
If dc>0 Then Begin
If dl>=dc Then Begin { 1er octant }
e:=dl; dl:=e*2; dc:=dc*2;
Repeat
DrwPnt(l1,c1,c);
l1:=l1+1;
If l1=l2 Then Exit;
e:=e-dc;
If e<0 Then Begin
c1:=c1+1;
e:=e+dl;
End;
Until False;
End Else Begin
e:=dc; dc:=e*2;
dl:=2*dl;
Repeat
DrwPnt(l1,c1,c);
c1:=c1+1; If c1=c2 Then Exit;
e:=e-dl;
If e<0 Then Begin
l1:=l1+1;
e:=e+dc
End;
Until False;
End;
End Else Begin
If dl>=-dc Then Begin { 8ieme octant }
e:=dl; dl:=e*2; dc:=dc*2;
Repeat
DrwPnt(l1,c1,c);
l1:=l1+1; If l1=l2 Then Exit;
e:=e+dc;
If e<0 Then Begin
c1:=c1-1;
e:=e+dl;
End;
Until False;
End Else Begin
e:=dc; dc:=e*2; dl:=dl*2;
Repeat
DrwPnt(l1,c1,c);
c1:=c1-1; If c1=c2 Then Exit;
e:=e+dl;
If e>0 Then Begin
l1:=l1+1;
e:=e+dc;
End;
Until False;
End;
End;
End Else Begin
Repeat
DrwPnt(l1,c1,c); l1:=l1+1;
Until (l1=l2);
End;
End Else Begin
dc:=c2-c1;
If dc<>0 Then Begin
If dc>0 Then Begin
If -dl>=dc Then Begin { 4ieme octant }
e:=dl;dl:=e*2; dc:=dc*2;
Repeat
DrwPnt(l1,c1,c);
l1:=l1-1; If l1=l2 Then Exit;
e:=e+dc;
If e>=0 Then Begin
c1:=c1+1;
e:=e+dl;
End;
Until False;
End Else Begin
e:=dc; dc:=e*2; dl:=2*dl;
Repeat
DrwPnt(l1,c1,c);
c1:=c1+1; If c1=c2 Then Exit;
e:=e+dl;
If e<=0 Then Begin
l1:=l1-1;
e:=e+dc;
End;
Until False;
End;
End Else Begin
If dl<=dc Then Begin { 5ieme octant }
e:=dl; dl:=e*2; dc:=dc*2;
Repeat
DrwPnt(l1,c1,c);
l1:=l1-1; If l1=l2 Then Exit;
e:=e-dc;
If e>=0 Then Begin
c1:=c1-1;
e:=e+dl;
End;
Until False;
End Else Begin
e:=dc; dc:=e*2; dl:=dl*2;
Repeat
DrwPnt(l1,c1,c);
c1:=c1-1; If c1=c2 Then Exit;
e:=e-dl;
If e>=0 Then Begin
l1:=l1-1;
e:=e+dc;
End;
Until False;
End;
End;
End Else Begin
Repeat
DrwPnt(l1,c1,c);
l1:=l1-1;
Until (l1=l2);
End;
End;
End Else Begin
dc:=c2-c1;
If dc<>0 Then Begin
If dc>0 Then Begin
Repeat
DrwPnt(l1,c1,c);
c1:=c1+1;
Until (c1=c2);
End Else Begin
Repeat
DrwPnt(l1,c1,c);
c1:=c1-1;
Until c1=c2;
End;
End;
End;
End;
Casio FX-502P /602P / 603P / FX180P+ / FX4000P / TI57 / TI66 / TI74 Basicalc / TI95 Procalc / HP12C / HP15C LE / DM41L / HP 30B / HP39GII / HP 48SX USA / 49G / 49g+ / 50G / 50G NewRPL / HP Prime / Oric 1 / Amstrad CPC 6128+ CM14 et MM12 / Alice 32
Re: Tracé d'un segment de droite.
Le Basic contient une routine de traçage de droites, de cercles aussi.
L