Tracé d'un segment de droite.

Je recherche. Tout et Rien, mais pas de petites annonces ici (pour les PA, c'est dans "Je donne, j'échange, j'achète et je vends")

Modérateur : Politburo

Répondre
kenneth
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 948
Enregistré le : 22 sept. 2010 13:48
Localisation : France PdD

Tracé d'un segment de droite.

Message par kenneth »

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...
Avatar du membre
bernouilli92
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5217
Enregistré le : 21 nov. 2012 13:03
Localisation : Ile de France

Re: Tracé d'un segment de droite.

Message par bernouilli92 »

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).
HP, Casio, Sharp, Psion, quelques TI et divers autres
Avatar du membre
gilles
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3100
Enregistré le : 17 avr. 2007 21:25
Localisation : 44
Contact :

Re: Tracé d'un segment de droite.

Message par gilles »

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
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3400
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Tracé d'un segment de droite.

Message par C.Ret »

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 ?
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.
kenneth
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 948
Enregistré le : 22 sept. 2010 13:48
Localisation : France PdD

Re: Tracé d'un segment de droite.

Message par kenneth »

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... :mrgreen:
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: Tracé d'un segment de droite.

Message par Gilles59 »

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
kenneth
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 948
Enregistré le : 22 sept. 2010 13:48
Localisation : France PdD

Re: Tracé d'un segment de droite.

Message par kenneth »

Merci pour l'info.
lisztfr
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 226
Enregistré le : 25 janv. 2013 00:49

Re: Tracé d'un segment de droite.

Message par lisztfr »

Le Basic contient une routine de traçage de droites, de cercles aussi. :-)
L
Répondre

Retourner vers « Recherche informations / technique / etc ... [pas de petites annonces ici] »