Forum: Mikrocontroller und Digitale Elektronik Linie zeichnen


von Steffen Hausinger (Gast)


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

von testest (Gast)


Lesenswert?

Bresenham-algorithmus
macht das nur mit integer add- und sub

von Rahul (Gast)


Lesenswert?

Irgendwo hab ich mal was zum Thema Geraden im Bereich der
Selbstbau-CNC-Fräsen gelesen, weiß jetzt aber nicht, wo ich's hab...

von Stefan K. (_sk_)


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

von Steffen Hausinger (Gast)


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

von Boxi B. (boxi)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.