Forum: Mikrocontroller und Digitale Elektronik wie Vektorgrafik anpassen ?


von Tom (Gast)


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

von hmann (Gast)


Lesenswert?

Vieleicht helfen dir die Links zum Thema Rotation in 2D weiter:

http://www.cs.unc.edu/~hoff/projects/comp236_ta/rotations/rotations.doc
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

von Holger B. (Gast)


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

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.