Rotationsproblem

Status
Nicht offen für weitere Antworten.

Quaxli

Top Contributor
Hallo,

der folgende Code ist Teil eines aus Primitven zusammengesetzten Objekts. Das Objekt soll mit einem Timer animiert werden. Die Methode des ActionListener sieht so aus:

Code:
	public void actionPerformed(ActionEvent e) {
		
		angle++;
		if(angle==360){
			angle = 0;
		}
		
		Transform3D temp = new Transform3D();
		tg3.getTransform(temp);
		temp.rotY(angle);
		temp.rotZ((float)Math.toRadians(90));
		temp.setTranslation(new Vector3f(.35f,0f,0.4f));
		t3d3.mul(temp);
		tg3.setTransform(temp);
		
				
	}

Das Problem sind rotY und rotZ. Sieht der Code aus wie oben, wird die Grafik wie gewünscht dargestellt, aber es rotiert nix. Wenn ich die beiden Zeilen vertausche, rotiert das Objekt, aber die 90°-Rotation zur Z-Achse fällt weg.
Was mache ich falsch? Ich will beide Rotationen haben, aber ich komme nicht drauf.
 

Marco13

Top Contributor
Ich nehme an, dass (sinngemäß) der Winkel sich bei jedem Aufruf um 1 erhöht. Er sollte dann aber auf jeden Fall in Radians umgerechnet werden, bevor er für die Rotation verwendet wird - wie bei den konstanen 90° auch.

Die Zeile
tg3.getTransform(temp);
Macht keinen Sinn, weil die Transformation in der nächsten Zeile
temp.rotY(angle);
schon überschrieben wird. Und das ist auch der Hauptgrund für den Fehler: Die Methode
trans.rotX(...)
bewirkt NICHT, dass bei einer bestehenden Rotation "weiter-rotiert" wird. Stattdessen wird die Matrix auf eine vollkommen NEUE Rotation gesetzt.

Eine Befehlsfolge wie
trans.rotX(Math.toRadians(1));
trans.rotX(Math.toRadians(1));
trans.rotX(Math.toRadians(1));
bewirkt also, dass die Matrix am Ende eine Roation um EIN Grad beschreibt (und nicht um 3).

Aber es stimmt schon - manchmal wäre praktisch, eine Methode zu haben wie

trans.multiplyWithRotationMatrixX(float rotationRad);

die Intern dann
Code:
    temp.rotX(rotationRad);
    trans.mul(temp);
ausführt. So fuhrwerkt man of mit irgendwelchen temp-Matrizen rum, die man oft nur für einen einzige Multiplikation erstellen muss... Die Abhilfe ergibt sich daraus sinngemäß etwa so:
Code:
      Transform3D trans = new Transform3D();
      Transform3D temp = new Transform3D();

      temp.rotY((float)Math.toRadians(angle));
      trans.mul(temp);
      temp.rotZ((float)Math.toRadians(90));
      trans.mul(temp);

      trans.setTranslation(new Vector3f(.35f,0f,0.4f)); // Das SETZT wirklich NUR die Translation!

      t3d3.mul(trans);
      tg3.setTransform(trans);
Ob die Reihenfolge die richtige ist, mußt du wissen ;)



EDIT: Ob man in Java3D wirklich einen Timer verwenden sollte, oder nicht doch lieber die (speziell dafür gemachten) Klassen "Alpha" und "RoationInterpolator" mußt du auch selbst wissen. Aber vielleicht brauchst du ja bestimmte Timer-Funktionalitäten in andem Zusammenhang nochmal....
 

Quaxli

Top Contributor
Ich nehme an, dass (sinngemäß) der Winkel sich bei jedem Aufruf um 1 erhöht. Er sollte dann aber auf jeden Fall in Radians umgerechnet werden, bevor er für die Rotation verwendet wird - wie bei den konstanen 90° auch.

Simmt, hatte ich übersehen. Ist mir nicht aufgefallen, weil die Drehung ja erst mal erfolgt ist. :wink:

Sonst funktioniert die Lösung wunderbar. Es ist halt etwas gewöhnungsbedürftig mit den Eigenheiten von Java3D.

EDIT: Ob man in Java3D wirklich einen Timer verwenden sollte, oder nicht doch lieber die (speziell dafür gemachten) Klassen "Alpha" und "RoationInterpolator" mußt du auch selbst wissen. Aber vielleicht brauchst du ja bestimmte Timer-Funktionalitäten in andem Zusammenhang nochmal....

Nö, Timer ist eigentlich nur die zweitbeste Lösung. :wink: Alpha schau' ich mir als nächstes an. Ich hab's mit Alpha im ersten Anlauf nicht gebacken gekriegt und brauchte erst mal 'n Erfolgserlebnis - was ja leider auch nicht geklappt. :cool:
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben