Forum: Mikrocontroller und Digitale Elektronik Sinus Funktion


von Mario (Gast)


Lesenswert?

Hallo zusammen,

ich versuche mich gerade mit meinem MSP an einem Grafikdisplay. Ich 
würde nun gerne eine Funktion schreiben, um Kreise zu zeichnen. Da 
brauche ich den Sinus zu und somit die math.h. Wenn ich die einbide, 
wird mein Code zu groß. Der IAR, also die kostenlose Version macht da 
nicht mit.

Kann auch keinen anderen Compiler nutzen, da ich mein USB-Modul damit 
nicht ans Laufen bekommen, also zum Flashen des MSP.


Hat jemand einmal eine Funktion geschrieben, um eine Sinus zu berechnen?
Wäre klasse, wenn mir da jemand weiterhelfen könnte.


Vielen Dank.
Grüße
Mario

von Karl H. (kbuchegg)


Lesenswert?

Um einen Kreis zu zeichnen brauchst du keinen Sinus.
Dafür gibt es eine Variante des Bresenham Algorithmus.

http://trevinca.ei.uvigo.es/~formella/doc/ig04/node51.html

Für Kreisbögen suche ich allerdings selbst noch was.

von Karl H. (kbuchegg)


Lesenswert?


von Hagen R. (hagen)


Lesenswert?

Ist zwar für WinAVR und nicht der vollständige Source meiner GLCD, aber 
es kann dir weiterhelfen.

Mit nachfolgendem Source kannst du Kreise, Elipsen und abgerundete 
Rechtecke zeichnen (Tonnen usw.). Linien Farbe und Füllfarbe werden 
berücksichtigt.

um einen Kreis zu zeichen zb.

glcdRoundRect(Left, Top, Left +X, Top +X, X / 2, X / 2, BLACK, WHITE);

dh. in einem Quadratischen Bereich auf dem Display wird der Kreis 
gezeichnet. Die abgerundeten Ecken müssen demzufolge halbe Seitenlänge 
besitzen = Radius desd Kreises.

Ist der rechteckige Bereich kein Quadrat würde man eine Ellipse 
zeichnen. Verringert man die Radien a,b so entsteht ein Rechteck mit 
abgerundeten Ecken.

Dh. mit dieser Funktion kannst du ausgehend vom einen Rechteck bis zu 
einem Kreis/Ellipse zeichnen.

Beachte das die interenen Datentypen nur Koordinaten im Bereich 0 bis 
255 -> Byte, fassen können. Wenn du einen größeren Bereich benötgst 
musst du diese Variablen anpassen -> uint32_t -> long etc.pp.

1
void glcdSetPixel4(glcdCoord_t x1, glcdCoord_t y1, glcdCoord_t x2, glcdCoord_t y2, glcdColor_t color) {
2
3
    glcdSetPixel(x1, y1, color);
4
    glcdSetPixel(x2, y1, color);
5
    glcdSetPixel(x1, y2, color);
6
    glcdSetPixel(x2, y2, color);
7
}
8
9
void glcdLine2(glcdCoord_t x1, glcdCoord_t y1, glcdCoord_t x2, glcdCoord_t y2, glcdColor_t color) {
10
11
    glcdFillRect(x1, y1, x2, y1, color);
12
    glcdFillRect(x1, y2, x2, y2, color);
13
}
14
15
void glcdRoundRect(glcdCoord_t x1, glcdCoord_t y1, glcdCoord_t x2, glcdCoord_t y2, glcdCoord_t a, glcdCoord_t b, glcdColor_t fgcolor, glcdColor_t bkcolor) {
16
17
    if (x1 > x2) glcdSwapCoord(x1, x2);
18
    if (y1 > y2) glcdSwapCoord(y1, y2);
19
    glcdCoord_t t;
20
    t = x2 - x1;
21
    t >>= 1;
22
    if (a > t) a = t;
23
    t = y2 - y1;
24
    t >>= 1;
25
    if (b > t) b = t;
26
    x1 += a;
27
    x2 -= a;
28
    if (fgcolor != NONE) glcdLine2(x1, y1, x2, y2, fgcolor);
29
    uint16_t as = a * a, bs = b * b;
30
    int32_t dx = 0, dy = as, ee = bs;
31
    dy *= b;
32
    ee += as / 4;
33
    ee -= dy;
34
    dy += dy;
35
    while (dx < dy) {
36
      if (fgcolor != NONE) glcdSetPixel4(x1, y1, x2, y2, fgcolor);
37
      x1--;
38
      x2++;
39
      if (ee >= 0) {
40
        y1++;
41
        y2--;
42
        dy -= as;
43
        dy -= as;
44
        ee -= dy;
45
        if (bkcolor != NONE) glcdLine2(x1, y1, x2, y2, bkcolor);
46
      }
47
      dx += bs;
48
      dx += bs;
49
      ee += bs;
50
      ee += dx;
51
  }
52
  int32_t tt = as;
53
    tt -= bs;
54
  tt *= 3;
55
  tt >>= 1;
56
  tt -= dx;
57
  tt -= dy;
58
  tt >>= 1;
59
    ee += tt;
60
    while (y1 <= y2) {
61
      if (bkcolor != NONE) glcdLine2(x1, y1, x2, y2, bkcolor);
62
      if (fgcolor != NONE) glcdSetPixel4(x1, y1, x2, y2, fgcolor);
63
      y1++;
64
      y2--;
65
      if (ee < 0) {
66
        x1--;
67
        x2++;
68
        a++;
69
        dx += bs;
70
        dx += bs;
71
        ee += dx;
72
      }
73
      dy -= as;
74
      dy -= as;
75
      ee += as;
76
      ee -= dy;
77
    }
78
}

von mr.chip (Gast)


Lesenswert?

Hallo

Wenn du genügend freies Flash/EEPROM hast, könntest du auch eine 
Lookup-Table für den Sinus erstellen. Mit 1 Byte pro Stelle und 128 
Stellen (zwischen 0 und 90 Grad) kriegt man schon sehr viel hin.

Gruss

Michael

von Philipp B. (philipp_burch)


Lesenswert?

Wenn er Hagens Code auf einen MSP portiert, dann sollte er den Datentyp 
eh auf uint16_t umstellen, da die MSPs 16-Bit Controller sind.

von Joe (Gast)


Lesenswert?

Mario,

bei der DEMO Version von IAR sind die Grenzen irgendwann mal erreicht.

http://kurt.on.ufanet.ru/

Hier findest du einen Programmer für deine MSP USB Schnittstelle, 
vielleicht hilft das weiter, MSPGCC und das Limit ist überwunden.

von Mario (Gast)


Lesenswert?

Vielen Dnak für die ganzen Tips!
Ich werde mich da nun erst einmal durchwurschteln :)

Vielen Dank.

Grüße

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.