www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Linie zeichnen


Autor: Steffen Hausinger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: testest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bresenham-algorithmus
macht das nur mit integer add- und sub

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Folgenden Bresenham-Code habe ich aus einem Wiki und in einigen Punkten
modifiziert:
void gbham(int8_t xstart, int8_t ystart, int8_t xend ,int8_t yend)
/*--------------------------------------------------------------
 * Bresenham-Algorithmus: Linien auf Rastergeräten zeichnen
 *
 * Eingabeparameter:
 *    int xstart, ystart     = Koordinaten des Startpunkts
 *    int xend, yend         = Koordinaten des Endpunkts
 *
 * Ausgabeparameter:
 *    int *npix                 = Anzahl der Pixel
 *    int (*xpix)[i],(*ypix)[i] = Koordinaten des i-ten Pixels
 *---------------------------------------------------------------
 */
{
  int8_t x, y, t, dist, xerr, yerr, dx, dy, incx, incy;

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

/* Vorzeichen des Inkrements bestimmen */
     if(dx<0)
     {
       incx = -1;
       dx = -dx;
     }
     else
       incx = dx ? 1 : 0;

     if(dy < 0)
     {
       incy = -1;
       dy = -dy;
     }
     else
       incy = dy ? 1 : 0;

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

/* Initialisierungen vor Schleifenbeginn */
     x = xstart;
     y = ystart;
     xerr = yerr = (dist) >> 1; //dx;
     // yerr = dist >> 1; //dy1;

/* Pixel berechnen */
     for(t = 0; t < dist; ++t)
     {
       setpixel(x, y);

       xerr += dx;
       yerr += dy;

       if(xerr >= dist)
       {
         xerr -= dist;
         x += incx;
       }

       if(yerr >= dist)
       {
         yerr -= dist;
         y += incy;
       }
     }

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

Viele Grüße, Stefan

Autor: Steffen Hausinger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Boxi Boxitec (boxi)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.