Main Menu

Berechnung Rotation

Started by Telix, November 25, 2013, 12:36:27 PM

Previous topic - Next topic

Telix

Gibt es eine Methode die ein Objec3D zu einem Punkt dreht?

Also sowas wie LookAt(SimpleVector)?

Wenn nicht, wie kann man das selber berechnen?

Wenn meine Figur nun nach rechts schaut und sie soll nach oben laufen.
Wie kann ich die Drehung berechnen?


Bzw. wie kann ich am besten berechnen, dass die Figur nach "oben" schauen soll.

ich hab als Beispiel X,Y vom Start und X,Y vom Ziel.
Wie bekomme ich nun raus wie sich die Figur drehen muss?

Danke vielmals!



EgonOlsen

Du könntest z.B. das hier benutzen: http://www.jpct.net/jpct-ae/doc/com/threed/jpct/SimpleVector.html#getRotationMatrix(com.threed.jpct.Matrix, com.threed.jpct.SimpleVector)

Die zu füllende Matrix kann die Rotationsmatrix des Objektes sein oder eine andere, wenn du den Übergang weicher ablaufen lassen willst.

Telix

Kannst du mir da ein wenig mehr erklären?
Ich bin nicht so der Pro der mit ner Matrix umgehen kann.

Mir fehlt grade das Verständnis wie ich von 2 Vectoren den Winkel bekommen kann.
Weil die Vectoren haben ja keine Ausrichtung. Es sind doch nur Punkte?

Wäre super lieb wenn du mir da ein wenig helfen könntest :)
Danke!

EgonOlsen

Also das kommt nun darauf an, was genau du tun willst. Das ist mir nicht 100% klar. Du hast eine Figur, die steht "irgendwie" gedreht? In diesem Fall vermutlich nur um die y-Achse? Und du willst jetzt den Winkel zwischen dieser Drehrichtung und...oben? Also quasi den Winkel, um den die Figur gedreht wurde? Wenn es das ist, dann geht sowas hier:


public static float deriveAngle(Matrix mat) {
float y = (float) Math.asin(Math.min(1f, Math.max(-1f, -mat.get(0, 2))));
float zd = mat.getZAxis().z;
if (zd < 0) {
     y = (float) (Math.PI / 2f + (Math.PI / 2f - y));
}
return y;
}


Wenn es das nicht ist, erklär nochmal genau, was du meinst.

Telix

Also ich habe meine Figur die schaut defaultmäßig nach rechts.

nun steht se auf dem Feld 7,7 (z,x) nun möchte ich, dass sie auf das feld 7,6 schaut. (also Links)

Wie bekomme ich nun raus, wie weit ich die Figur drehen muss, dass sie auf Feld 7,6 schaut?

Ist es nun die Methode die du geschrieben hast?

EgonOlsen

-180°? Wie kannst du dich denn auf dem Feld bewegen und drehen? Schrittweise oder zumindest feldweise oder völlig frei?

Telix

naja ich weiß ja nicht wie die figur grade steht und wohin sie grade schaut. (Sprich die Figur kann somit in 360° schauen)
Sprich ich müsste von der aktuellen ausrichtung wissen wie weit ich se drehen muss.

Das Schrittweise würde ich dann selbst machen, aber dafür müsste ich ja den "max" Wert wissen :)

EgonOlsen

Ja, dann müsste das etwa sowas wie da oben sein. Das ist quasi der Winkel zwischen Figur (d.h. der Rotationsmatrix) und oben. Den Rest müsstest du dann selbst addieren. Diese Methode funktioniert aber nur, wenn die Drehung in einer Ebene bleibt.

Telix

Irgendwie bin ich zu blöde :(

Was mach ich falsch?

public void lookAt(SimpleCord pos) {
SimpleVector startVector = this.getRotationPivot();
SimpleVector endVector = new SimpleVector(pos.X * 2, startVector.y, pos.Y * 2);
Matrix mat = startVector.getRotationMatrix(endVector);
float angle = deriveAngle(mat);
rotateY(angle);
Log.w("ANGLE", Float.toString(angle));
}

public float deriveAngle(Matrix mat) {
float y = (float) Math.asin(Math.min(1f, Math.max(-1f, -mat.get(0, 2))));
float zd = mat.getZAxis().z;
if (zd < 0) {
     y = (float) (Math.PI / 2f + (Math.PI / 2f - y));
}
return y;
}

EgonOlsen

Du musst vor dem rotateY die alte Rotation zurücksetzen. Ansonsten addieren die sich. Das geht am schnellsten mit Object3D.clearRotation().

Telix

Das ist leider nicht mein Problem :(
Ich hab mir mal die Zahlen genau angeschaut und an sich ist der Weg schon der richtige.

Siehe Tabelle:
https://docs.google.com/spreadsheet/ccc?key=0Am6BJ5tHhzH_dFYwek9Ba215Z183NlFtYnJ3eDVMalE&usp=sharing

Frage ist, warum der Wert so klein ist und ich diesen mit 35 mal nehmen muss?
Und warum erhalte ich bei nach Oben und Unten schauen beides eine 0?

Somit kann ich nicht entscheiden ob er nach oben oder unten schauen muss :(

Danke!!

EgonOlsen

Nee, das ist nicht der richtige Weg. Es ist mir vorhin nicht aufgefallen, aber du mischt da die 3D-Räume zusammen. Das Rotation-Pivot ist im Objektraum, dein Blickpunkt im liegt aber in der Welt. Und der Vektor des Endpunktes ist auch niemals der UP-Vektor. Und es ist auch nicht genau das, was ich meinte....aber egal. Wenn du das so machen willst, dann musst du eher:


  • Richtungsvektor r zum lookAt-Punkte berechnen (endVector-getTransformedCenter())
  • Davon die Rotationsmatrix m bestimmen: r.getRotationMatrix(up); up ist dabei in deinem Fall wohl immer (0,-1,0)
  • float angle=deriveAngle(m);
  • Aktuelle Rotation mit clearRotation() löschen, mit angle um y-Achse rotieren

...irgendwie so...

Telix

Also das mit der 35 ist nun weg und ich bekomme direkt den Wert zum drehen.
Jedoch nur für links und rechts :( Bei Oben und Unten bekomme ich immer 0.

startVector = 6,0,6
endvector = 6,0,7

oder

endVector = 6,0,5


public void lookAt(SimpleCord pos) {
SimpleVector startVector = this.getTranslation();
SimpleVector endVector = new SimpleVector(pos.X * 2, startVector.y, pos.Y * 2);

SimpleVector diffVector = endVector.calcSub(startVector);
Matrix mat = diffVector.getRotationMatrix(new SimpleVector(0, -1, 0));

Log.w("STARTVECTOR", startVector.toString());
Log.w("ENDVECTOR", endVector.toString());

float angle = (float) deriveAngle(mat);
clearRotation();
rotateY(angle + (float)(0.5f * Math.PI));
Log.w("ANGLE", Float.toString(angle));
}


public float deriveAngle(Matrix mat) {
// float y = (float) Math.asin(Math.min(1f, Math.max(-1f, -mat.get(0, 2))));
float y = (float) Math.asin(-mat.get(0, 2));
return y;
}

EgonOlsen

Logisch, weil der Arkussinus keine Werte außerhalb von +-Pi/2 liefern kann. Deswegen war da ja mal der zusätzliche Code in der Methode, denn du rausgeworfen hast. Damit sollte erkannt werden, ob die Blickrichtung zwischen 180 und 270 Grad liegt und entsprechend PI addiert. Was ist denn, wenn du die Methode wieder so verwendest, wie sie mal war?

Telix

arg -.- das is mir nun aber peinlich :(

ich hab das rausgenommen, da ich dachte ich verändere die Z Achse garnicht.
Sorry :( nun gehts...