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

1

19.06.2008, 23:22

Rotation von Objekten um deren eigene Achse

Hallo!

Ich versuche mir derzeit eine Kamera-Klasse zu schreiben und stehe jetzt vor einem Problem: Ich will in der Lage sein, die Kamera relativ, d.h. um ihre eigene Achse rotieren zu lassen. Ich glaube das ist eine ganz gängige Hürde für Einsteiger, auch ich bin da leider keine Ausnahme.

Eine mögliche Lösung, die ich mir ausgedacht habe, wäre folgende:
1.) Ich verschiebe das Objekt zurück auf den Ursprung des Weltkoordinatensystems
2.) Ich wende die Rotationsmatrix (für das Weltkoordinantensystem) an.
3.) Ich verschiebe das Objekt an seine ursprüngliche Position zurück

In der Theorie klappt das bei mir. Bei meiner Google-Recherche bin ich jetzt aber auf was noch viel tolleres gestoßen, was mich derzeit noch davon abhält, meine Idee umzusetzen, weil ich erstmal wissen will, was da passiert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Rotieren des Objekts, um seine eigenen Achsen 

void tbObject::RotateRel(const tbVector3& vRotation) 
{ 
    // Rotation um die x-Achse des Objekts 

    tbMatrix mRotation(tbMatrixRotationAxis(m_vXAxis, vRotation.x)); 
    m_vYAxis = tbVector3TransformNormal(m_vYAxis, mRotation); 
    m_vZAxis = tbVector3Cross(m_vXAxis, m_vYAxis); 

    // Rotation um die y-Achse des Objekts 

    mRotation = tbMatrixRotationAxis(m_vYAxis, vRotation.y); 
    m_vXAxis = tbVector3TransformNormal(m_vXAxis, mRotation); 
    m_vZAxis = tbVector3Cross(m_vXAxis, m_vYAxis); 

    // Rotation um die z-Achse des Objekts 

    mRotation = tbMatrixRotationAxis(m_vZAxis, vRotation.z); 
    m_vXAxis = tbVector3TransformNormal(m_vXAxis, mRotation); 
    m_vYAxis = tbVector3TransformNormal(m_vYAxis, mRotation); 

    // Matrizen aktualisieren 

    Update(); 
}

Ein Codeausschnitt aus der Tribase-Engine, hier im Forum gefunden. Ich würde gerne dahinter kommen, wie das funktioniert. Das Objekt speichert wohl drei Vektoren, die sein Koordinatensystem beschreiben (bzw. wie es in der Weltmatrix liegt). Im Endeffekt dreimal der selbe Code, soweit auch verständlich. Es wird eine mysteriöse Achsenrotationsmatrix erzeugt und auf den Vektor angewandt. Danach wird die zweite von der Transformation beeinflusste Achse über das Kreuzprodukt "wiederhergestellt". Wo es bei mir jetzt aber aufhört, ist eben diese Matrix zur Rotation um eine Achse, hier die betreffende Codepassage:

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
// Rotationsmatrix für Rotation um eine beliebige Achse berechnen

TRIBASE_API tbMatrix tbMatrixRotationAxis(const tbVector3& v,
                                          const float f)
{
    // Sinus und Kosinus berechnen

    const float fSin = sinf(-f);
    const float fCos = cosf(-f);
    const float fOneMinusCos = 1.0f - fCos;

    // Achsenvektor normalisieren

    const tbVector3 vAxis(tbVector3Normalize(v));

    // Matrix erstellen

    return tbMatrix((vAxis.x * vAxis.x) * fOneMinusCos + fCos,
                    (vAxis.x * vAxis.y) * fOneMinusCos - (vAxis.z * fSin),
                    (vAxis.x * vAxis.z) * fOneMinusCos + (vAxis.y * fSin),
                    0.0f,
                    (vAxis.y * vAxis.x) * fOneMinusCos + (vAxis.z * fSin),
                    (vAxis.y * vAxis.y) * fOneMinusCos + fCos,
                    (vAxis.y * vAxis.z) * fOneMinusCos - (vAxis.x * fSin),
                    0.0f,
                    (vAxis.z * vAxis.x) * fOneMinusCos - (vAxis.y * fSin),
                    (vAxis.z * vAxis.y) * fOneMinusCos + (vAxis.x * fSin),
                    (vAxis.z * vAxis.z) * fOneMinusCos + fCos,
                    0.0f,
                    0.0f,
                    0.0f,
                    0.0f,
                    1.0f);
}


Ich denke ohne Hilfe komme ich da nicht dahinter. Das ganze ist mir ein ziemliches Rätsel und ich bräuchte die Mathematik dahinter ein wenig besser aufgeschlüsselt.

Wäre für Hilfe sehr dankbar!

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

2

20.06.2008, 00:02

(Warnung: Hab nich so die Ahnung :))
Ich glaube dein Ansatz (erst verschieben, dann drehen, dann wieder zurueckverschieben) steckt genauso in den Funktionen die hier verwendet werden. Du kannst ja im voraus die Matritzen multiplizieren und dann sozusagen eine "Verschiebe-Rotations-Verschiebe-Matrix" auf den Vektor anwenden.

Mit dem kleinen Detail dass hier ein normalisierter Richtungsvektor manipuliert wird. Der kann natuerlich garnicht verschoben werden. Mit tbMatrixRotationAxis wird einfach eine Matrix erzeugt die (eigentlich einen Punkt) um eine angegebene Achse um einen angegebenen Winkel dreht. Da das ganze ein Richtungsvektor ist wird danach wieder normiert.
Wenn du wissen willst wie man genau auf diese Matrix kommt musst du wohl warten bis jemand kommt der Ahnung hat :) Aber genau das ist ja das tolle daran: Wenn man weiss was eine solche Matrix tut, braucht man sich nicht mehr darum kuemmern wie genau sie zustande kommt.
"Have you tried turning it off and on again?"

3

20.06.2008, 09:20

das funktioniert etwas anders.
wenn du ein objekt um seine eigene achse drehen willst, musst ja schon ein eigenes Koordinatensystem(in Form von 3 Achsen) für dein Objekt bestehen. da sich das Objekt um seine Eigene Achse Drehen soll, drehst du nicht das Objekt, sondern die Achsen-also das Koordinatensystem. Genau das macht die Fkt!

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

4

20.06.2008, 16:13

das, was du gern möchtest nennt man vektorkamera. zera hat das schon richtig erklärt.

nochmal vllt ein wenig anders erklärt:

du definierst dir wie zera schon gesagt hat ein lokales koordinatensystem aus drei vektoren. diese sollten zueinander orthogonal sein. mit hilfe dieser dreier vektoren ist das möglich, deine unabhängige dehung zu vollziehen.

wir gehen mal von DirectX mit Left-handed Koordinatensystem aus, da wären das als grundvektoren in positive Z-Richtung schauend folgende vektoren!

C-/C++-Quelltext

1
2
3
Vector3 vXCoord = { 1,0,0 }; //Vektor in x-Richtung

Vector3 vYCoord = { 0,1,0 }; //Vektor in y-Richtung

Vector3 vZCoord = { 0,0,1 }; //Vektor in z-Richtung


wenn du dich jetz drehen möchtest, unabhängig von verschiebung, dann solltest du das immer anhand dieser vektoren tun! drehst du dich also z. b. um deine x-achse, tust du folgendes:

C-/C++-Quelltext

1
2
3
4
5
6
7
//erzeuge eine Rotationsmatrix an einer beliebigen achse, hier x-Achse

Matrix temp = RotationAxis(vXCoord,Drehwinkel);

//Rotiere die anderen beiden Vektoren mit, Damit die Drehung glückt!

//die beiden anderen vektoren müssen immer mitdrehen, sonst wird das nichts!

vYCoord = Vector3TransformCoord(temp,vYCoord);
vZCoord = Vector3TransformCoord(temp,vZCoord);


das wäre für die x-achse drehen. entsprechend kanst du dich um die anderen achsen drehen, indem du einen andreen Vektor für die Drehachse nimmst (für z-achse nimmste vZCoord :)) und entsprechend immer die anderen beiden vektoren mitdrehst.

dann wieder zum schluss alles in die Matrix eintragen, so wie es schon gepostet ist.

5

21.06.2008, 15:24

Danke für eure tollen Antworten! OK, das Funktionsprinzip zu verstehen ist ja schon fast die halbe Miete, für mich wäre jetzt nur noch interessant, wie das ganze aus mathematischer Sicht funktioniert.

Ich werde erstmal selbst nochmal versuchen, da etwas mehr durchzusteigen, hab wohl generell noch etwas nachholbedarf.

Ich meld mich dann, wenn sich ne konkretere Frage auftut. ;)

Werbeanzeige