www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Sinus Funktion


Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht 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.

void glcdSetPixel4(glcdCoord_t x1, glcdCoord_t y1, glcdCoord_t x2, glcdCoord_t y2, glcdColor_t color) {

    glcdSetPixel(x1, y1, color);
    glcdSetPixel(x2, y1, color);
    glcdSetPixel(x1, y2, color);
    glcdSetPixel(x2, y2, color);
}

void glcdLine2(glcdCoord_t x1, glcdCoord_t y1, glcdCoord_t x2, glcdCoord_t y2, glcdColor_t color) {

    glcdFillRect(x1, y1, x2, y1, color);
    glcdFillRect(x1, y2, x2, y2, color);
}

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) {

    if (x1 > x2) glcdSwapCoord(x1, x2);
    if (y1 > y2) glcdSwapCoord(y1, y2);
    glcdCoord_t t;
    t = x2 - x1;
    t >>= 1;
    if (a > t) a = t;
    t = y2 - y1;
    t >>= 1;
    if (b > t) b = t;
    x1 += a;
    x2 -= a;
    if (fgcolor != NONE) glcdLine2(x1, y1, x2, y2, fgcolor);
    uint16_t as = a * a, bs = b * b;
    int32_t dx = 0, dy = as, ee = bs;
    dy *= b;
    ee += as / 4;
    ee -= dy;
    dy += dy;
    while (dx < dy) {
      if (fgcolor != NONE) glcdSetPixel4(x1, y1, x2, y2, fgcolor);
      x1--;
      x2++;
      if (ee >= 0) {
        y1++;
        y2--;
        dy -= as;
        dy -= as;
        ee -= dy;
        if (bkcolor != NONE) glcdLine2(x1, y1, x2, y2, bkcolor);
      }
      dx += bs;
      dx += bs;
      ee += bs;
      ee += dx;
  }
  int32_t tt = as;
    tt -= bs;
  tt *= 3;
  tt >>= 1;
  tt -= dx;
  tt -= dy;
  tt >>= 1;
    ee += tt;
    while (y1 <= y2) {
      if (bkcolor != NONE) glcdLine2(x1, y1, x2, y2, bkcolor);
      if (fgcolor != NONE) glcdSetPixel4(x1, y1, x2, y2, fgcolor);
      y1++;
      y2--;
      if (ee < 0) {
        x1--;
        x2++;
        a++;
        dx += bs;
        dx += bs;
        ee += dx;
      }
      dy -= as;
      dy -= as;
      ee += as;
      ee -= dy;
    }
}

Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mario (Gast)
Datum:

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

Vielen Dank.

Grüße

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.