Hallo
Habe so ein tolles Dipslay von Display 3000 mit Atmel 128
und möchte einen Kreis darstellen oder Kurven.
Ich habe einen Befehl der einzelne Pixel setzt an Xund Y Pos.
Wie kann man die einzelen pixel für einen Kreis berechnen???
Vielen Dank
Bresenham lernt man nicht in der Schule, sondern im Internet
Aber die Berechnungen sind einfache Additionen und Schiebeoperationen,
das ist wirklich nicht schwer, Herr Lehrer
Ich habe bei Bresenham immer ein Verständnisproblem: Wie kann ich
Kreissegmente (effizient) realisieren, die nicht aus den Achtelkreisen
bestehen (z.B. Kreisbogen von "2 Uhr" nach "1 Uhr")?
> Ich habe bei Bresenham immer ein Verständnisproblem: Wie kann ich> Kreissegmente (effizient) realisieren, die nicht aus den> Achtelkreisen bestehen (z.B. Kreisbogen von "2 Uhr" nach "1
Uhr")?
Das würde mich auch interessieren.
Weiss jemand, ob es dazu so etwas "einfaches" wie den Bresenham
gibt?
Und wenn wir schon dabei sind, was ist mit Ellipsen, usw.?
Ralf
Ich will nicht unbedingt etwas Zeichnen, sondern etwas fräsen...
Hab mich aber noch nicht weiter mit entsprechenden CNC-Seiten
auseinandergesetzt.
Eigentlich müsste man für den entsprechenden Radius die Punkte in ein
Feld schreiben (was natürlich recht groß werden kann), dann die dem
Kreissegment entsprecheden Punkte aus den Teilkreisen
"zusammenbasteln".
Das Feld würde natürlich mit dem Radius wachsen.
@Christoph Kessler
In der ursprünglichen Frage war nicht die Rede von einer schnellen
Routine, sondern generell, wie zeichne ich einen Kreis, wenn ich eine
Funktion zum Setzen von Pixeln habe.
Wenn einer schon mal was von Kreisradius, Sinus und Cosinus (6 Klasse?)
gehört hat, dann sollte er wissen wie es geht - auch für CNC oder
Plotter Anwendungen...
Die Fräsplotter arbeiten, soweit ich weiß, immer noch mit dem guten
alten HPGL, da gibts einen Kreisbogenbefehl. Das ist üblicherweise aus
Geradenstücken angenähert. Den Bresenham müßte man vermutlich auf einem
45Grad-Segmentpunkt starten, aber das erste Stück weglassen, bis ein
Schwellwert überschritten ist - den müßte man aber erst mal berechnen.
Eine Alternative zu Bresenham ist der CORDIC-Algorithmus, mit dem kann
man Sinus und Cosinus berechnen, dann kann Herr Lehrer auch eine
Kreisgleichung benutzen, ohne Hochsprache.
@Lehrer: Den Schüler will ich sehen, der in der 6.Klasse schon mit Sinus
und Cosinus "rummacht".
Trogometrie ist wohl eher Stoff ab der 8./9. Klasse (Gymnasium).
In der 6. Klasse kommen so nette Sachen wie Wurzelrechnung, gemischte
Brüche (oder wie die heissen) dran.
Habe mal meine alten Schulbücher angeschaut.
Winkelfunktionen wurden damals in der 7 Klasse Realschule (1980, Baden-
Württemberg) abgearbeitet.
Ich wundere mich, dass die "Nordstaaten" heute überhaupt noch solche
komplexe Sachverhalte im Lehrplan haben... ;-)
Hab den Algorithmus auch gefunden, aber diese Routine zeichnet ja nur
den Kreisumfang.
Wir haben gerade ein Projekt an der Hochschule, wo wir Vollkreise
(Fläche ausgemahlt) auf einem Grafikdisplay anzeigen wollen. Kann mir
zufällig jemand einen C-Code empfehlen, wodurch man das realisieren
könnte. Wäre super, wenn jemand antworten würde, sind grad total am
Verzweifeln.
Danke Im Vorraus
Gute Idee :-).
Wenn ich den Quellcode, den Philipp Karbach gepostet habe, und einfach
am Schluss den Radius dekrementiere (Radius--), und den neue Radius der
Funktion nochmal übergeben in ner Schleife, bis der Radius 0 ist, würde
das auch gehen?
Es gibt natürlich viele Möglichkeiten, den Kreislinienalgorithmus
zum Kreisscheibenalgorithmus aufzupimpen. Hier ist die in meinen Augen
fast optimale Variante. Zusätzlich zur Berechnung der Randpunkte eines
Achtelkreises müssen vertikale Linien gezeichnet werden, die zusammen
die Kreisfläche bilden:
1
voidvline(intx,inty1,inty2){
2
inty;
3
4
for(y=y1;y<=y2;y++)
5
setPixel(x,y);
6
}
7
8
voidrasterDisk(intx0,inty0,intradius){
9
intf=1-radius;
10
intddF_x=0;
11
intddF_y=-2*radius;
12
intx=0;
13
inty=radius;
14
15
vline(x0,y0-radius,y0+radius);
16
17
while(x<y){
18
if(f>=0){
19
vline(x0+y,y0-x,y0+x);
20
vline(x0-y,y0-x,y0+x);
21
22
y--;
23
ddF_y+=2;
24
f+=ddF_y;
25
}
26
x++;
27
ddF_x+=2;
28
f+=ddF_x+1;
29
30
vline(x0+x,y0-y,y0+y);
31
vline(x0-x,y0-y,y0+y);
32
}
33
}
Das Implementierungsbeispiel für vline() kann für LCDs optimiert
werden, da dort typischerweise bis zu 8 Pixel mit einem Zugriff
gesetzt werden können.
Der Algorithmus zeichnet - abhängig vom Radius - oft zwei der
vertikalen Linien doppelt. Das macht ihn nicht wirklich schlecht, aber
es ist unschön. Auch der Kreislinienalgorithmus hat diese Schwäche,
nur fällt sie dort nicht so arg ins Gewicht, da dort nur ein paar (4
oder 8) Pixel doppelt gezeichnet werden. Beides kann man verbessern,
doch habe ich im Moment keinen Kopf dazu ;-)
Es dürfte relativ sinnfrei sein, zuerst die Randpixel zu
malen, wenn dann sowieso eine Linie zu/von diesem Randpixel
geht.
Du solltest dir erst mal die Theorie zu Bresenham reinziehen.
Zuerst der Linen - Bresenham (um mit dem grundsätzlichen Verfahren
warm zu werden) und dann mit der Variation die auf Kreise
losgelassen wird.
> Danke für die schnelle Hilfe. Würde das auch funktionieren?
Der Aufruf von rasterCircle am Ende der While-Schleife scheint doppelt
gemoppelt. Außerdem kann ich mir vorstellen (hab's nicht ausprobiert),
dass die Kreisfläche mit dem Verfahren nicht vollständig gefüllt wird,
da in den Regionen, wo die Linie schräg verläuft, der Pixelabstand > 1
ist. Dadurch könnte die Fläche im Bereich der beiden 45°-Achsen Löcher
aufweisen. Aber probier's doch einfach mal aus.
Außerdem wird für jedes gesetzte Pixel deutlich mehr gerechnet als für
das Zeichnen von vertikalen Linien.