/* Fonction pour tracer une ligne non antialiasée de(X0,Y0) à (X1,Y1), en * utilisant simplement une approche d'accumulation d'erreur en virgule fixe. * Testée avec Borland C++ 4.02 en modèle small par Jim Mischel 12/16/94. */ extern void DrawPixel(int, int, int); /* Traceur de ligne non antialiasée. * (X0,Y0),(X1,Y1) =ligne à tracer, Color = couleur de tracer */ void DrawLine(int X0, int Y0, int X1, int Y1, int Color) { unsigned long ErrorAcc, ErrorAdj; int DeltaX, DeltaY, XDir, Temp; /* S'assure que la ligne passe de haut en bas */ if (Y0 > Y1) { Temp = Y0; Y0 = Y1; Y1 = Temp; Temp = X0; X0 = X1; X1 = Temp; } DrawPixel(X0, Y0, Color); /* trace le pixel initial */ if ((DeltaX = X1 - X0) >= 0) { XDir = 1; } else { XDir = -1; DeltaX = -DeltaX; /* rend DeltaX positif */ } if ((DeltaY = Y1 - Y0) == 0) /* fini s'il y a seulement un point dans la ligne */ if (DeltaX == 0) return; ErrorAcc = 0x8000; /* initialise l'accumulateur d'erreur de la ligne à 0,5 , Nous pouvons donc avancer quand nous sommes à mi-chemin du prochain pixel */ /*Est-ce une ligne d'axe principal X ou Y ? */ if (DeltaY > DeltaX) { /*Ligne d'axe principal Y; calcule la part fractionnaire sur 16 bits d'un pixel qui avance sur X chaque fois qu'Y avance d'1 pixel */ ErrorAdj = ((((unsigned long)DeltaX << 17) / (unsigned long)DeltaY) + 1) >> 1; /* Affiche tous les pixels situés entre le premier et le dernier */ do { ErrorAcc += ErrorAdj; /* calcule l'erreur de ce pixel */ if (ErrorAcc & ~0xFFFFL) { /* L'accumulateur d'erreur est retourné, avançons la coordonnée X */ X0 += XDir; ErrorAcc &= 0xFFFFL; /* efface la part entière du résultat */ } Y0++; /* Y principal, nous avançons toujours sur Y */ DrawPixel(X0, Y0, Color); } while (--DeltaY); return; } /* Ligne d'axe principal X; calcule la part fractionnaire en virgule fixe sur 16 bits d'un pixel qui avance sur Y chaque fois que X avance d'1 pixel */ ErrorAdj = ((((unsigned long)DeltaY << 17) / (unsigned long)DeltaX) + 1) >> 1; /* Affiche tous les pixels restant */ do { ErrorAcc += ErrorAdj; /* calcule l'erreur de ce pixel */ if (ErrorAcc & ~0xFFFFL) { /* L'accumulateur d'erreur est retourné, avançons la coordonnée Y */ Y0++; ErrorAcc &= 0xFFFFL; /* efface la part entière du résultat */ } X0 += XDir; /* X principal, avançons toujours sur X */ DrawPixel(X0, Y0, Color); } while (--DeltaX); }