Forum: Mikrocontroller und Digitale Elektronik GLCD Kreise mit variabler Rahmenstärke


von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

zur Zeit veruche ich eine Bibliothek für mein Grafik LCD ein bisschen zu 
erweitern. Eine Kreiszeichenfunktion (Bresenham Algorithmus) war schon 
implementiert, die soweit ganz gut arbeitet.

Jetzt zu meinem Problem: Genau diese Funktion habe ich so erweitert, 
dass auch die Rahmenstärke mit angegeben werden kann. Siehe Anhang. Dazu 
zeichne ich einfach kleinere Kreise je nach Rahmenstärke. Dummerweise 
werden einige Pixel nicht gesetzt. Siehe Bild.

Im Internet habe ich schon viel gelesen, aber dazu keine Lösung 
gefunden. Kann es sein, dass genau so eine Funktion mit dem Bresenham 
Algorithmus nicht möglich ist? Kann das irgendjemand bestätigen? Wie 
könnte man es anders realisieren?

Gruß Andreas

von g457 (Gast)


Lesenswert?

> Im Internet habe ich schon viel gelesen, aber dazu keine Lösung
> gefunden.

Dann hast Du nicht richtig gesucht :-)

> Kann es sein, dass genau so eine Funktion mit dem Bresenham
> Algorithmus nicht möglich ist?

Doch.

> Kann das irgendjemand bestätigen?

Nein.

> Wie könnte man es anders realisieren?

Ausgelassene Pixel auffüllen (inneren und äusseren Kreis zeichnen, 
dazwischen auffüllen - kann ineffizient sein). Oder den Bresenham 
erweitern (kann effizient sein). Oder mehr Kreise zeichnen (sehr 
ineffizient aber einfach).

HTH

von Andreas (Gast)


Lesenswert?

g457 schrieb:
> Dann hast Du nicht richtig gesucht :-)

Hm für einen Link wäre ich sehr dankbar.

g457 schrieb:
> Oder mehr Kreise zeichnen (sehr
> ineffizient aber einfach)

Was meinst du genau mit mehr Kreise zeichen? Wie soll ich denn zwischen 
Rahmen Innen- und Außenseite noch mehr Kreise zeichnen?

Andreas

von oog (Gast)


Lesenswert?

Du kannst anstelle von Punkten Quadrate zeichnen.

Z.B. anstelle von diesem Punkt ...
1
LCD_SetPoint(xc+x, yc+y, col);

... vier Punkt als kleines Quadrat
1
LCD_SetPoint(xc+x, yc+y, col);
2
LCD_SetPoint(xc+x+1, yc+y, col);
3
LCD_SetPoint(xc+x, yc+y+1, col);
4
LCD_SetPoint(xc+x+1, yc+y+1, col);

Da kann man noch weiter optimieren (z.B. vertikale und horizontale Linie 
anstelle von Quadraten je nach Zeichenrichtung).

von W.S. (Gast)


Lesenswert?

Dir bleibt in solchen Fällen wohl nix anderes übrig, als den mittleren 
Kreisradius zu bestimmen, dann die zu setzende "Pixelgröße" in X und Y 
aus der gewünschten Strichstärke zu bestimmen und dann einen Kreis per 
Bresenham zu zeichnen und dabei um jedes errechnete Pixel einfach ein 
Kreuz "+" von Pixeln sowohl in X als auch in Y-Richtung zu zeichnen. 
Also anstelle eines Pixels ein Kreuz zeichnen - sozusagen.

W.S.

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Ok vielen Dank für die Antworten.
Hab jetzt einfach mal ein bisschen mit dem Code rumgespielt. Die 
drawcircle Funktion um folgende Zeile erweitert:
Zeile 20: drawCirclePart(xc, yc, x, y, col);

Jetzt funzt es perfekt. Nur leider hab ich keine Ahnung warum :-). Werd 
mir morgen mal den Code genauer anschaun.

Andreas

von Andreas (Gast)


Lesenswert?

Ok jetzt hab ichs verstanden. Mit der erweiterten Zeile zeichne ich 
einfach beide Pixel, die zur Auswahl stehen. Normalerweise wird das mit 
dem geringerem Abstand zum "perfekten" Kreis gezeichnet.

Werds jetzt einfach so machen: Für den inneren Kreis und für den äußeren 
Kreis nehme ich die alte Version, für die Kreise dazwischen die Neue.

Ok alles klar. Danke nochmal.

Andreas

von Axel S. (a-za-z0-9)


Lesenswert?

g457 schrieb:
> Oder mehr Kreise zeichnen (sehr ineffizient aber einfach).

Ich denke mal, genau dann bekommt man das Ergebnis, das der TE zeigt: 
wenn man einfach viele Kreise mit Radius r= r1..r2 mit Inkrement 1 
übereinander zeichnet. Denn obwohl man in der Horizontalen und 
Vertikalen jeden Punkt zwischen r1 und r2 Abstand von x0 (bzw. y0) 
erwischt, ist das für Punkte irgendwo dazwischen eben nicht mehr 
garantiert.

Ich denke mal, eine Erweiterung des Bresenham-Algorithmus ist gefragt. 
Statt nur jeden Punkt auf einem Achtelkreis (und dessen 7 symmetrische 
Brüder) zu setzen, müßte man horizontale (bzw. vertikale, je nach 
Quadrant) Linien zwischen den Punkten für den Kreis mit Radius r1 bzw. 
r2 zeichnen.

Floodfill ist nicht nur ineffizient, sondern scheitert auch für 
Spezialfälle wie r2=r1+1 etc.


XL

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.