Linie zeichnen

Gast #316859
Lesenswert?
• ▲
▼
Hallo

Wie zeichne ich am Besten eine Linie aus einzelnen Pixeln? Ich habe
eine Funktion, mit der ich einzelne Pixel setzen kann. Auf dieser Basis
möchte ich eine Funktion schreiben, mit der ich eine Linie zeichnen
kann. Das Display ist aus einem Nokia 3310 (84x48 Pixel) und ich
programmiere mit WinAVR.

Ich probiere es gerade über die Geradengleichung, aber so wirklich toll
ist das nicht. Für y=m*x benötige ich erstens 16-Bit (Festkomma 10.6)
für die Steigung m (minimale Steigung ist ja 2/84). Zweitens muss ich x
dann ja auch mit 2/84 auflösen, damit ich jedes y mitbekomme, wenn ich
y=m*x rechne. Ergo muss ich zwei 16-Bit Zahlen multiplizieren und das
für jedes Pixel - dauert ein bißchen lang :-( Oder ist da irgendwo noch
ein Denkfehler drin?!

Habt ihr einen Ansatz für mich? Ich hab im Archiv die Routine vom 6100
gefunden. Die ist aber etwas spärlich kommentiert wenn man nicht weiß,
wie's funktioniert...

Grüsse,
Steffen
#316862
Lesenswert?
• ▲
▼
Folgenden Bresenham-Code habe ich aus einem Wiki und in einigen Punkten
modifiziert:
1
void gbham(int8_t xstart, int8_t ystart, int8_t xend ,int8_t yend)
2
/*--------------------------------------------------------------
3
 * Bresenham-Algorithmus: Linien auf Rastergeräten zeichnen
4
 *
5
 * Eingabeparameter:
6
 *    int xstart, ystart     = Koordinaten des Startpunkts
7
 *    int xend, yend         = Koordinaten des Endpunkts
8
 *
9
 * Ausgabeparameter:
10
 *    int *npix                 = Anzahl der Pixel
11
 *    int (*xpix)[i],(*ypix)[i] = Koordinaten des i-ten Pixels
12
 *---------------------------------------------------------------
13
 */
14
{
15
  int8_t x, y, t, dist, xerr, yerr, dx, dy, incx, incy;
16

17
/* Entfernung in beiden Dimensionen berechnen */
18
     dx = xend - xstart;
19
     dy = yend - ystart;
20

21
/* Vorzeichen des Inkrements bestimmen */
22
     if(dx<0)
23
     {
24
       incx = -1;
25
       dx = -dx;
26
     }
27
     else
28
       incx = dx ? 1 : 0;
29

30
     if(dy < 0)
31
     {
32
       incy = -1;
33
       dy = -dy;
34
     }
35
     else
36
       incy = dy ? 1 : 0;
37

38
/* feststellen, welche Entfernung größer ist */
39
     dist = (dx > dy)?dx:dy;
40

41
/* Initialisierungen vor Schleifenbeginn */
42
     x = xstart;
43
     y = ystart;
44
     xerr = yerr = (dist) >> 1; //dx;
45
     // yerr = dist >> 1; //dy1;
46

47
/* Pixel berechnen */
48
     for(t = 0; t < dist; ++t)
49
     {
50
       setpixel(x, y);
51

52
       xerr += dx;
53
       yerr += dy;
54

55
       if(xerr >= dist)
56
       {
57
         xerr -= dist;
58
         x += incx;
59
       }
60

61
       if(yerr >= dist)
62
       {
63
         yerr -= dist;
64
         y += incy;
65
       }
66
     }
67

68
     setpixel(xend, yend);
69
} /* gbham() */

Viele Grüße, Stefan
Gast #316863
Lesenswert?
• ▲
▼
Hallo

Vielen Dank für die Tipps und danke für den Code! Er funktioniert
einwandfrei! Ich musste ihn nur ein bißchen anpassen (u.a. xerr, yerr
und dist als uint8_t deklarieren, da er sonst mit den 84x48 nicht
klarkommt).

Ihr habt mir eine Menge Arbeit erspart :-)

Grüsse,
Steffen
#572485
Lesenswert?
• ▲
▼
Also, wenn ich mir den Algorithmus hier anschaue, meine ich, dass diese 
"Anpassungen" grundsätzlich nötig sind, dass der Code allgemein 
funktioniert.
Außerdem muß man noch vor der Bestimmung der größten Distanz den Betrag 
von dx und dy bilden und mit diesen Werten weiterrechnen.
Sonst werden nur Linien, die von oben links nach unten rechts gehen, 
richtig angezeigt.

Heißt also, im Wikipedia, wo ich auch gerade nachgeschaut habe, stimmt's 
auch nicht...

Wie seht ihr das?

Gruß
Boxi

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.