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
Irgendwo hab ich mal was zum Thema Geraden im Bereich der Selbstbau-CNC-Fräsen gelesen, weiß jetzt aber nicht, wo ich's hab...
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.