# Rotationsproblem



## Quaxli (30. Jul 2007)

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:


```
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 (30. Jul 2007)

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 

```
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:

```
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 (31. Jul 2007)

> 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.


----------

