Ein Objekt auf ein anderes ausrichten?
-
Hi zusammen,
muss für die Uni ein 3D-Billiardspiel entwickeln.
Hänge grade an folgender Problemstellung:- BilliardQueue liegt irgendwo auf dem Tisch rum
- Beim drücken von "A" verschiebe ich den Queue auf die eyePosition der Kamera.Was ich jetzt möchte, dass der Queue automatisch auf die weiße Kugel zeigt.
Ich komm einfach nicht drauf, wie ich den Winkel berechnenen kann.Ich habe jetzt meinen Queue zwar an eine Position geschoben und diese Position kenne ich auch, aber was mir GLAUBE ich fehlt, ist der Richtungsvektor des Queues.
Ich hoffe ihr wisst was ich meine. Hier eine kleine Grafik, die es hoffentlich besser beschreibt:
[URL=http://img381.imageshack.us/my.php?image=problemstellungtm9.gif][/URL]Prinzipiell: Was muss ich errechnen um den Queue auf die weiße Kugel zeigen zu lassen?
Tausend Dank im vorruas. Ihr seit meine letzte Rettung.
Greetings, MisterDan
-
Warum nochmal ?
Du brauchst eine Transformationsmatrix. Diese besteht aus 3 (orthogonalen) normierten Basisvektoren die einen Vektorraum aufspannen sowie einem Translationsvektor.
Der erster Basisvektor verlaeuft von der Kameraposition zur Kugel (Vektor nach Vorne)
Der zweite ist das Kreuzprodukt (liefert einen orthogonalen Vektor) aus erstem und dem Normalenvektor der Tischebene (Vektor nach Oben)
Der dritte ist das Kreuzprodukt aus den vorherigen beiden (Vektor zur Seite)
Die Reihenfolge der Basisvektoren ist abhaengig von der Ausrichtung des Queues im untransformierten Objektraum, die Position ist abhaengig vom Ursprungspunkt.
Liegt die Spitze des Queues am Ursprung, nimmst Du einfach die Position der Kugel minus "ein bischen" des ersten Basisvektors (Stossrichtung).Effektiv macht die LookAt-Funktion das Gleiche um eine Kameramatrix aus Position und Target zu erzeugen, entspricht also genau der Vorgehensweise die _titan99_ schon im ersten Thread vorgeschlagen hat.
Alternativ kannst Du Dir auch die eulerschen Winkel entsprechend Deiner Skizze vom Einheitskreis ableiten.
-
hellihjb schrieb:
Alternativ kannst Du Dir auch die eulerschen Winkel entsprechend Deiner Skizze vom Einheitskreis ableiten.
Ähh, sorry aber kannst du mir vll ein paar Anhaltspunkte geben wie ich dort dabei vorgehen muss?
-
Wenn Du von oben auf Deinen Tisch guckst denkst Du Dir einen Kreis um Deine anzuvisierende Kugel auf dem sich die Kamera bewegt.
Normierst Du den Vektor von Kugel zu Kamera, hast Du die Koordinaten auf dem Einheitskreis.
Angewandte Trigonometrie liefert Dir den Winkel des Vektors zu den karthesischen Achsen:
a= atan2(y,x)
-
Richtig: atan2(...) verwendet man hier, wollte ich auch gerade vorschlagen; wird auch bei irrlicht engine eingesetzt.
-
Vielleicht so was:
#define ASIN(x) asin(x)*180.0/M_PI struct vector3f { float X, Y, Z; }; float getDistance(vector3f Pos1, vector3f Pos2) { return sqrt( (Pos1.X - Pos2.X)*(Pos1.X - Pos2.X) + (Pos1.Y - Pos2.Y)*(Pos1.Y - Pos2.Y) + (Pos1.Z - Pos2.Z)*(Pos1.Z - Pos2.Z) ); } float getDistance(float X1, float Y1, float X2, float Y2) { return sqrt( (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) ); } void LookAt(vector3f ObjectPosition, vector3f &ObjRotation, vector3f LookAtPosition) { /* Temporary variable */ vector3f Rot; /* Calculate rotation */ Rot.X = - ASIN( (LookAtPosition.Y - Pos.Y) / getDistance(ObjectPosition, LookAtPosition) ); Rot.Y = ASIN( (LookAtPosition.X - Pos.X) / getDistance(ObjectPosition.X, ObjectPosition.Z, LookAtPosition.X, LookAtPosition.Z) ); Rot.Z = 0.0f; if (Pos.Z < Position.Z) Rot.Y = 180.0f - Rot.Y; /* Settings */ ObjectRotation = Rot; }Gruß Lukas