Forum: Mikrocontroller und Digitale Elektronik Kleine c-routine um auf Pixelbasis Kreise und Striche zu zeichnen


von Martin S. (mmaddin)


Lesenswert?

Hi zusammen,

ich suche eine kleine c-Datei in der wenige einfache routinen zum Kreise 
und Striche Zeichnen sind.

Basieren sollte alles auf einer set_pixel(x,y,color) - Funktion.

void draw_circle(uint8_t x,uint8_t y, uint8_t r, uint8_t color);
void draw_line(uint8_t x1,uint8_t y1,uint8_t x2, uint8_t y2, uint8_t 
color);

Wären völlig ausreichend. Bild ist nur 32y64 Pixel.

Danke

von Thomas W. (datenreisender)


Lesenswert?

Das Such-Wort waere Bresenham-Algorithmus.

von Wastl (hartundweichware)


Lesenswert?

Martin S. schrieb:
> ich suche eine kleine c-Datei in der wenige einfache routinen zum Kreise
> und Striche Zeichnen sind.

Eine kleine C-Datei wirst du nicht finden, aber eine grosse. Dort
must du suchen nach Drawline und Drawcircle. Diese Funktionen
musst du ein eine kleine C-Datei kopieren, und voilá, schon hast
du sie.

Die erwähnte (grosse) Datei findest du in allen üblichen
Ansammlungen ("Libs") von Funktionen zum Ansteuern von
TFT-Displays.

Oder war deine Suchanfrage so zu verstehen dass wir das
machen sollen?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?


von Johann L. (gjlayde) Benutzerseite


Lesenswert?


von Martin S. (mmaddin)


Lesenswert?

Top, danke, hab was

Beitrag #7950207 wurde vom Autor gelöscht.
von Martin S. (mmaddin)


Lesenswert?

glcd

Läuft schon

: Bearbeitet durch User
von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Sowas mache ich immer als "Fingerübung" in Programmierkursen. Will 
sagen, das kann man mit wenigen Zeilen auch selber schreiben. Hier eine 
Beschreibung der Algorithmen:

1. Line, hat Koordinaten der Endpunkte XA,YA und XE,YE

a) Länge der Linie nach Pythagoras berechnen
b) die Differenz DX aus XE-XA und DY aus YE-YA bestimmen
c) die Schrittweite für X und Y bestimmen: XS = DX/Länge, YS = DY/Länge
c) dann, beginnend mit XA,YA die Länge entlang bis zu XE,YE iterieren 
und jedesmal SX zu X und SY zu Y dazu addieren

2. Kreis, hat Koordinaten des Mittelpunkes XM,YM und einen Radius R

a) Länge des Umfanges über 2  Pi  R berechnen
b) die Zahl 2 Pi durch die Länge teilen, das ist die Schrittweite
c) von 0 nach 2 * PI in der ermittelten Schrittweite iterieren, dabei
die Koordinaten der zu setzenden Pixel (X,Y) berechnen. POS ist der 
Momentanwert:

x = XM + sin(POS) * R, y = YM + cos(POS) * R

***

: Bearbeitet durch User
von Martin S. (mmaddin)


Lesenswert?

Interessant wäre wie man die "Strichdicke" bei Kreisen realisieren 
könnte.

Erster Gedanke wäre ja einfach zwei ein-strich Dicke Kreise mit einem 
Pixel Radius weniger ineinander zu zeichnen, doch dann entstehen immer 
mal Löcher im Kreis, was ja auch logisch ist, aber wie das zu machen 
wäre, wäre interessant für mich ebenso wie das Füllen von Kreisen...

/*********************************************************************** 
******/
/* Interne Hilfsroutine zum kreiszeichen, spiegelt die Segmente 
*/
/*********************************************************************** 
******/

void circlepoints(unsigned int cx, unsigned int cy, unsigned int x,
                  unsigned int y, unsigned char color)
{
   if (x == 0) {
      lcdg_drawpixel(cx,cy+y, color);
      lcdg_drawpixel(cx,cy-y, color);
      lcdg_drawpixel(cx+y,cy, color);
      lcdg_drawpixel(cx-y,cy, color);
   } else
   if (x == y) {
      lcdg_drawpixel(cx+x,cy+y, color);
      lcdg_drawpixel(cx-x,cy+y, color);
      lcdg_drawpixel(cx+x,cy-y, color);
      lcdg_drawpixel(cx-x,cy-y, color);
   } else
   if (x<y) {
      lcdg_drawpixel(cx+x,cy+y, color);
      lcdg_drawpixel(cx-x,cy+y, color);
      lcdg_drawpixel(cx+x,cy-y, color);
      lcdg_drawpixel(cx-x,cy-y, color);
      lcdg_drawpixel(cx+y,cy+x, color);
      lcdg_drawpixel(cx-y,cy+x, color);
      lcdg_drawpixel(cx+y,cy-x, color);
      lcdg_drawpixel(cx-y,cy-x, color);
   }
}




/*********************************************************************** 
******/
/* Zeichnet einen Kreis um die angebene Position 
*/
/*********************************************************************** 
******/

void lcdg_circle(unsigned char xCenter, unsigned char yCenter,
                 unsigned char radius, unsigned char color)
{
   unsigned int x= 0;
   unsigned int y= radius;
   signed int p= (5- radius*4)/4;

   circlepoints(xCenter, yCenter, x, y, color);
   while (x<y) {
      x++;
      if (p<0) {
   p += 2 * x + 1;
      } else {
   y--;
   p += 2 * (x-y)+1;
      }
      circlepoints(xCenter, yCenter, x, y, color);
   }
}

von Wastl (hartundweichware)


Lesenswert?

Frank E. schrieb:
> Hier eine Beschreibung der Algorithmen:

Wieso beschreibst du hier Algorithmen? Der TO sucht doch nach
einer kleinen C-Datei wo alles mundgerecht serviert wird. Er
will nicht nach Algorithmus eine Funktion programmieren.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Wastl schrieb:
> Frank E. schrieb:
>> Hier eine Beschreibung der Algorithmen:
>
> Wieso beschreibst du hier Algorithmen? Der TO sucht doch nach
> einer kleinen C-Datei wo alles mundgerecht serviert wird. Er
> will nicht nach Algorithmus eine Funktion programmieren.

Ich wollte ihn damit animieren, es vielleicht doch zu probieren :-)

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Martin S. schrieb:
> Interessant wäre wie man die "Strichdicke" bei Kreisen realisieren
> könnte.
>

Wenn man für alle berechneten Werte Float oder Double nimmt, etstehen 
keine Lücken. Das ist sicher nicht perfekt für eine hoch optimierte 
Grafik-Lib, zum Grundverständnis reicht es allemal.

Die Liniendicke kann man, wenn vorhanden, über den Parameter "penwidth" 
vorher einstellen, ebenso die Farbe. Wenn nicht, muss man kleine 
gefüllte Kreise oder Quadrate verwenden und jedesmal "händisch" die 
Pixel in der passenden Farbe hinmalen.

von Wastl (hartundweichware)


Lesenswert?

Frank E. schrieb:
> muss man kleine gefüllte Kreise oder Quadrate verwenden

Wie geht das wenn:

Martin S. schrieb:
> Bild ist nur 32y64 Pixel.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Wastl schrieb:
> Frank E. schrieb:
>> muss man kleine gefüllte Kreise oder Quadrate verwenden
>
> Wie geht das wenn:
>
> Martin S. schrieb:
>> Bild ist nur 32y64 Pixel.

Ups, das sind ja quasi Icons. Sowas habe ich tatsächlich noch nie 
algorithmisch gemacht, sondern manuell Pixel by Pixel geklickert ...

von Norbert (der_norbert)


Lesenswert?

Wastl schrieb:
> Frank E. schrieb:
>> muss man kleine gefüllte Kreise oder Quadrate verwenden
>
> Wie geht das wenn:
>
> Martin S. schrieb:
>> Bild ist nur 32y64 Pixel.

Man malt eine Ellipse und schaut von der Seite im 60° Winkel auf die 
Anzeige.

von Bruno V. (bruno_v)


Lesenswert?

Frank E. schrieb:
> x = XM + sin(POS) * R, y = YM + cos(POS) * R

Das ist als Fingerübung ok. Habe ich im 9ten Schuljahr auch so gemacht 
(wollte ein Zeichenprogramm auf deren Acorn erstellen, ja, Größenwahn). 
Aber das ist nicht Kanonen auf Spatzen, sondern Flugzeugträger zum 
Milchholen.

(Über die Jahre habe ich dann nach und nach gesehen, wie sowas in 
einfach und Integer)

: Bearbeitet durch User
von Sebastian W. (wangnick)


Lesenswert?


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.