Sinus Funktion

Gast #466459
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
#466471
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
}
Gast #466472
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren