Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

09.03.2012, 19:44

Ok, bitte les dringend nochmal ein Tutorial über Matrizen. Insbesondere über Matrixmultiplikation, warum die Reihenfolge dort nicht egal ist und wie man auf die Richtige Reihenfolge kommt. Dann erledigt sich dein Problem von selbst, aber hier geht es nicht um ein kleines Detail oder einen Denkanstoß, sondern du bist einfach noch nicht tief genug im Thema drin, um damit zu arbeiten.

Ein Anfang wäre beispielsweise dieser Artikel:
http://wiki.delphigl.com/index.php/Tutorial_Matrix2
(die Theorie funktioniert analog mit DX oder auch allen anderem)
Lieber dumm fragen, als dumm bleiben!

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

12

10.03.2012, 14:39

OK. Habe nochmal Tutorials durch gemacht. Und bin nun zu folgendem Code gekommen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
/* Translation entfernen */
Actual_M.m41 = 0;
Actual_M.m42 = 0;
Actual_M.m43 = 0;
Actual_M.m14 = 0;
Actual_M.m24 = 0;
Actual_M.m34 = 0;
Actual_M.m44 = 1;

mMatrix = MatrixRotation(Vector3(MatrixRotationXToAngle(Actual_M),MatrixRotationYToAngle(Actual_M),MatrixRotationZToAngle(Actual_M)));

In Actual_M steht nach der Bearbeitung mit der Translation eine Rotation drinnen. Mit dem darauf folgendem Code dürfte eigentlich nichts verändert sein. Leider doch. Der Code für die Rotation zu Winkeln:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
float   MatrixRotationXToAngle( Matrix mWorld )
{
    float Angle = atan2(mWorld.m32,mWorld.m33);
    if(Angle < 0)
    {
        Angle += (2*PI);
    }

    return Angle;
}

float   MatrixRotationYToAngle( Matrix mWorld )
{
    float Angle = -asinf(mWorld.m31);
    if(Angle < 0)
    {
        Angle += (2*PI);
    }

    return Angle;
}

float   MatrixRotationZToAngle( Matrix mWorld )
{
    float Angle = atan2(mWorld.m21,mWorld.m11);
    if(Angle < 0)
    {
        Angle += (2*PI);
    }

    return Angle;
}

Die Funktion MatrixRotation:

C-/C++-Quelltext

1
2
3
4
Matrix MatrixRotation( const Vector3& v )
{
    return MatrixRotationZ( v.z ) * MatrixRotationX( v.x ) *  MatrixRotationY( v.y );
}

Hier die Soll und ist Rotation:
Soll:

Quellcode

1
2
3
X: 1.57
Y: 0.00
Z: 1.34

Ist:

Quellcode

1
2
3
X: -1.57
Y: 0.00
Z: -1.34

Danke.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

13

10.03.2012, 14:59

Warum glaubst du, dass deine MatrixToAngle Funktionen funktionieren? Weil sie das Gegenteil tun, wie die Berechnung einer einfachen Rotationsmatrix? Was wenn es keine Rotationsmatrix, sondern irgendeine beleibige Transformationsmatrix ist, erwartest du da noch sinnvolle Ergebnisse?
Wenn du mehrere Matrizen multiplizierst, und irgendwo in der Kette mal eine X-Rotation drin steckte, erwartest du dann genau diesen Winkel zurück zu bekommen? Wenn du mittlerweile weißt, dass die Multiplikation NICHT kommutativ ist, also X*Y*Z eine ganz andere Matrix als Y*X*Z ergibt, und du von diesem Ergebnis einfach nur auf 1-2 Werte zugriefst und dadurch herausfinden willst, um welchen Winkel gedreht wurde, glaubst du, das kann gehen?

Nun, schon möglich, dass es irgendwie geht, aber es dürfte zumindest komplizierter sein, als deine Variante. Merk dir einfach: Es gelten bei Matrizen nicht mehr alle Rechengesetze so wie bei "normalen" Zahlen, alles was nicht explizit erlaubt ist, ist erstmal verboten und kann nur Blödsinn liefern.
Bei Matrizen wirst du oft ne Menge rumrechnen und bekommst am Ende irgendein Ergebnis, es ist hier besonders wichtig, bei jedem Schritt zu wissen, was er macht, und warum er hier erlaubt ist. Durch rumprobieren wirst du in den seltensten Fällen auf ein korrektes Ergebnis kommen. Glaub mir, ich spreche aus Erfahrung, bei Matrizen ist genaues Vorgehen viel viel wichtiger, als bei anderen Rechenaufgaben.

Und nochwas: Wieso interessiert dich der Winkel überhaupt? Denke abstrakter! Denke bei Matrizen an allgemeine Transformationen, die du hintereinander ausführen kannst (durch Matrixmultiplikation) und die du Rückgängig machen kannst (durch invertierte Matrizen). Du brauchst für dein Problem garantiert keine Winkelzerlegung, du musst einfach nur die Matrizen richtig multiplizieren.
Lieber dumm fragen, als dumm bleiben!

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

14

10.03.2012, 15:15

Zitat


Du brauchst für dein Problem garantiert keine Winkelzerlegung, du musst einfach nur die Matrizen richtig multiplizieren.

Naja schon den die Mtarix die ich bekomme, bekomme ich von einer Funktion auf die ich keinen Einfluss habe. Und ich dachte das Funktioniert weil mir das Internet so eine Antwort geliefert hat :)
Also ich muss schon die drei Winkel auslesen. Oder gibt es eine andere Möglichkeit einen Winkel zu eine Matrix zu Addieren?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

15

10.03.2012, 16:09

In der Regel, kann es dir ganz egal sein, wie Matrizen intern funktionieren. Du kannst die Funktionen als Blackbox benutzen, was sie eigentlich tun ist doch egal, solange du weißt, was das Ergebnis ist.

In deinem Fall: Du willst z.B. ein Objekt um 45 Grad drehen. Und dann nochmal um 35 Grad drehen. Deine Idee ist, "ich drehe das Objekt um 45+35 Grad, also um 80 Grad". Ist ansich auch richtig, aber viel zu kompliziert, bzw. konkret gedacht. Dreh doch einfach erst um 45 Grad und dann um 35 Grad. Du hast beide Matrizen, wenn du diese kombinierst (d.h. multiplizierst), hast du eine Matrix, die erst um 45 Grad dreht und dann um 35 Grad, aber in einem Schritt.
Das entspricht übrigens nicht dem "um 80 Grad drehen". In diesem trivialen Beispiel schon, aber im allgemeinen nicht und das ist sehr wichtig zu verstehen. Wenn du mehrere Transformationen hintereinder ausführst, ist die Reihenfolge entscheidend.
Lieber dumm fragen, als dumm bleiben!

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

16

10.03.2012, 16:44

Fast. Das Objekt ist schon gedreht also in der Matrix steh schon was worauf ich kein Einfluss gehabt hatte. Jetzt muss ich noch einen Winkel um die y Achse dazurechnen. Das geht aber nicht so wie ich das gemacht habe :) Also wie geht das?
Danke :)

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

17

10.03.2012, 17:17

Rotationsmatrix um die Y Achse erstellen und mit der Objektmatrix multiplizieren. Mach dir aber vorher klar, wierum (AxB oder BxA.!
Lieber dumm fragen, als dumm bleiben!

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

18

10.03.2012, 19:10

!!! EDIT: !!! Sry war etwas durcheinander. Ich meinte, dass sich mein Würfel jetzt je nach Winkel dauernd dreht und zwar schneller oder langsamer O.o

OK. Habe ich gemacht:

C-/C++-Quelltext

1
2
3
addm = MatrixRotationY(CamHandler->GetCameraAngleX() - off1);
Actual_M = addm * Actual_M;
// Actual_M = Actual_M* addm;

Leider ohne Erfolg. Mein Körper dreht sich jetzt auf X: 0 Y: 0 Z: 0 aber die Y Rotation funktioniert. Ich habe AxB und BxA probiert. Komischerweise gleiches Ergebnis. Also mein Körper dreht sich einfach auf 0,0,0. Die Rotation ist irgendwie noch fehlerhaft :/ Aber was habe ich falsch gemacht?
Danke

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »FSA« (10.03.2012, 19:33)


19

10.03.2012, 22:28

Ja hm, dann ist dein ganzen Programm irgendwie komisch. So pauschal lässt sich da wenig zu sagen, kannst du das Projekt mal hochladen? Hilfreich wäre es, vorher alles rauszuschmeißen, was nichts mit dem Problem zu tun hat. (Also das Projekt kopieren, und solange Logik und Ressourcen rausschmeißen, bis nur noch das Problem übrig bleibt, es sich aber alles noch kompilieren und ausführen lässt)
Lieber dumm fragen, als dumm bleiben!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

20

11.03.2012, 00:42

Vergiss für nen Moment mal wie du meinst es erreichen zu müssen und sag uns doch einfach mal was du eigentlich erreichen willst.
Ich hab sehr stark das Gefühl, dass es, für was auch immer es sein mag, eine sehr viel simplere Lösung gibt...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (11.03.2012, 00:47)


Werbeanzeige