www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik wie Vektorgrafik anpassen ?


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Ich versuche gerade die Vektorgrafik routinen von
www.mikrocontroller.com auf mein 128*64 Pixel groses Display
anzupassen. Klappt nur leider noch nicht so recht. Ich habe bissher die
Funktionen zum zeichnen eines Strichs und zum löschen des Displays
geschrieben und sie Funktionieren genauso wie beim Original Programm.
Ich hatte nun die Hoffnung das ich die folgende Funktion so übernehmen
könnte:

void RotatingObject(int W1,int W2,int W3, int x_Pos,int y_Pos,int
OBJ[][6],int cnt,int size)
{
 int M[4][4];
 register int g,i;
 int z1,z2 ;
 int x1,x2 ;
 int y1,y2 ;
 int xr1,xr2 ;
 int yr1,yr2 ;
 int zr1,zr2 ;

  // Rotation-Matrix
  // calculates the new position of the single vectors
  M[1][1] = ((long) COS[W2]*COS[W3]) /256;
  M[2][1] = ((long)-COS[W2]*SIN[W3]) /256;
  M[3][1] = SIN[W2];

  M[1][2] =  ((long)COS[W1]*SIN[W3])/256  +
((long)SIN[W1]*SIN[W2]*COS[W3])/(256*256);
  M[2][2] =  ((long)COS[W1]*COS[W3])/256  -
((long)SIN[W1]*SIN[W2]*SIN[W3])/(256*256);
  M[3][2] = ((long)-SIN[W1]*COS[W2])/256;

  M[1][3] =  ((long)SIN[W1]*SIN[W3])/256  -
((long)COS[W1]*SIN[W2]*COS[W3])/(256*256);
  M[2][3] =  ((long)SIN[W1]*COS[W3])/256  +
((long)COS[W1]*SIN[W2]*SIN[W3])/(256*256);
  M[3][3] =  ((long)COS[W1]*COS[W2])/256;

 if(size!=128)  // recalculate the size
  {
   for(g=1;g<4;g++) for(i=1;i<4;i++) M[g][i] =  (M[g][i] * size) /
128;
  };

 for(i=0;i<cnt;i++)  // draws the single lines
  {
    // get the line (from x1,y1,z1 to x2,y2,z2)
    x1 = OBJ[i][0];
    y1 = OBJ[i][1];
    z1 = OBJ[i][2];
    x2 = OBJ[i][3];
    y2 = OBJ[i][4];
    z2 = OBJ[i][5];

    // Convert the vector through the Rotation-Matrix
    xr1 = (M[1][1] * x1)/MUL + (M[2][1]*y1)/MUL + (M[3][1]*z1)/MUL;
    yr1 = (M[1][2] * x1)/MUL + (M[2][2]*y1)/MUL + (M[3][2]*z1)/MUL;
    xr2 = (M[1][1] * x2)/MUL + (M[2][1]*y2)/MUL + (M[3][1]*z2)/MUL;
    yr2 = (M[1][2] * x2)/MUL + (M[2][2]*y2)/MUL + (M[3][2]*z2)/MUL;

  // Draws the line
    LCD_Line( xr1 + x_Pos, yr1 + y_Pos, xr2 + x_Pos, yr2 + y_Pos);
   }
}

Und ich hiermit eine Pyramide gezeichnet bekomme:
// Pyramide
#define PYR_A    00,+00,-10
#define PYR_B   -15,-8,+10
#define PYR_C   +15,-8,+10
#define PYR_D   +00,17,+10
#define CNT_PYR  6
const int PYR[CNT_UFO][6]=
       {
    { PYR_A,PYR_B},
    { PYR_A,PYR_D},
    { PYR_A,PYR_C},
    { PYR_B,PYR_C},
    { PYR_B,PYR_D},
    { PYR_D,PYR_C}
     };
Klappt nur leider nicht, ich habe nur völlig sinnlose schräge lininien
auf dem Display.
Meine Frage wäre nun: Kann mir jemand etwas genauer erklären wie die
Funktion überhaupt funtioniert und wieso für einen Punkt der Pyramide 3
Werte definiert werden, ich habe doch nur 2 Dimmensionen auf dem
Display? Und wozu das 00 und +00?

Danke!
Gruß Tom

Autor: hmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vieleicht helfen dir die Links zum Thema Rotation in 2D weiter:

http://www.cs.unc.edu/~hoff/projects/comp236_ta/ro...
http://msl.cs.uiuc.edu/planning/node65.html

Genau erklären kann ich dir die Funktion nicht, aber wenn du eine
Rotationsmatrix und einen Vektor dazu hast must du das ganze eigtl nur
multiplizieren. Ich denke mit den Links kommst du da weiter.

Ciao
  hmann

Autor: Holger B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tom,

ich habe die Originalfunktion geschrieben.
Die Punkte, aus denen das Objekt besteht sind 3D-Punkte in X, Y und
Z-Koordinaten.
Die können mittels der Rotationsmatrix (M[1][1] bis M[3][3]) zum
3D-Koordinatensystem verdreht werden. Diese Matrix besteht im Prinzip
aus Vektoren mit konstanter Länge, die nur um die Winkel W1, W2 und W3
verdreht liegen. Jeder Punkt Deines Objekts wird mit diesen Vektoren
multipliziert.

Ausserdem wird die Grösse des Objekts verändert, indem die
Rotationsmatrix vergrössert oder Verkleinert wird.
 for(g=1;g<4;g++) for(i=1;i<4;i++) M[g][i] =  (M[g][i] * size) /
128;
Die Grössenänderung kannst Du vielleicht mal entfernen, indem Du die
Grösse auf 128 setzt.
Die Winkel solltest Du zunächst alle auf 0 setzen.

Zum Test kannst Du auch das Objekt in der Funktion direkt anzeigen,
anstelle es zu übergeben:

 for(i=0;i<CNT_PYR;i++)  // draws the single lines
  {
    // get the line (from x1,y1,z1 to x2,y2,z2)
    x1 = PYR[i][0];
    y1 = PYR[i][1];
    z1 = PYR[i][2];
    x2 = PYR[i][3];
    y2 = PYR[i][4];
    z2 = PYR[i][5];
...

In der Deklaration der Pyramide ist mit offensichtlich ein Fehler
unterlaufen:
#define CNT_PYR  6
const int PYR[CNT_PYR][6]=
....
Muss es eigentlich lauten.
+00 und 00 ist natürlich das selbe.

Gruss,
Holge

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.