# Rotation in java 3d - diffs between setEuler, rotX, Y, Z etc.

21 replies [Last post]
bennidd
Offline
Joined: 2006-02-14

Hello,

i really confused about rotation. i've wrote a simple programm, where you can switch between euler rotation and rotX multiply rotY multiply rotZ (in this order).

what i want is a rotation only around the axis of the object (in this case a cube).
Means for me: i've stuck three sticks in the cube, like the painted axis in the programm, and only around them i rotate.

but none of these rotation do it right:
a)the rotX*rotY*rotZ rotate only around the z-axis correctly
b)the euler only around the x-axis correctly

the programm is available under:
http://rcswww.urz.tu-dresden.de/~s8400000/java3d.jar

start it with "java -cp java3d.jar java3d.HelloJava3Da"

usage:
arrow keys and pgDw, pgUp for object rotation
+/- "global" zoom
a,w,s,d - "global" translation

My question is:
1. how are rotation in java3d is implemented (sometimes the axis are transformated too, sometimes not -> see a) ) and where is my fault in understanding

and

2. which things/matrix should i use to solve the problem

Sven

Christophe LOREK

gimbal lock is the flaw in using Euler angles, it's a mathematical problem
(a good solution to that kind of trouble is using quaternions), you should

"The gimbal lock is caused by X and Z axis being in the same order after
rotating the Y axis 90/-90 degrees. And this will give you no control over
those axis. "

----- Original Message -----
From:
To:
Sent: Friday, September 16, 2005 11:00 AM
Subject: Re: Rotation in java 3d - diffs between setEuler, rotX, Y, Z etc.

> i think gimbal lock is a mechanical problem
> but here there is only maths...
>
> but maybe i'm wrong, so please tell me how u would solve this problem (may
by presenting the right matrix)...
>
> Sven
> ---
> [Message sent by forum member 'bennidd' (sven)]
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
> For additional commands, e-mail: interest-help@java3d.dev.java.net
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net

bennidd
Offline
Joined: 2006-02-14

ok, my fault

but it (gimbal lock) is a problem, which comes along euler-angles.
but i get also in trouble with the multiplied rotation-matrices...

Sven

Message was edited by: bennidd

bennidd
Offline
Joined: 2006-02-14

thanks a lot for your replies, now i know what is gimbal lock and that the pasted code solve it, so now euler transformation/rotation is the same like the matrix-multiplication...

first we have one problem and two approaches
now we've reduce the euler "approach" to matrix-approach,
but the problem is still unsolved...

Message was edited by: bennidd

John P H Steele

I have a comment that may help, although I am not up on the java3D
implementations so what I'm going to say is pertinent to the
fundamental operation of Euler angles (rotations), what I could call
body rotations, as opposed to fixed frame rotations.
When computing the effect of a sequence of rotations (e.g., roll,
pitch, yaw) the frames about which the rotations are executed makes a
big difference. Frame transformations are not communicative, i.e.,
you can't reverse the order and get the same thing.
So if you are doing rotations about the axis of the object of
interest, i.e., Euler angles, then the matrices are multiplied in the
order in which the rotations are executed, e.g., rot(a,x) followed by
rot(b, y), followed by rot(c, z) would be multipled as follows
rot(a,x) . rot(b, y) . rot(c, z).
If however you are executing rotations about the fixed axes of the
"world" then each of the rotations is premultipled, i.e.,
rot(c, z) . rot(b,y) . rot(a,x).
This is because the operations are really a "similarity transform".
Your matrix multiplies will need to mimic this sequence.

Perhaps this is why the rotations don't seem to be coming out correctly.

Hope this helps.
-js

On Sep 16, 2005, at 7:18 AM, java3d-interest@javadesktop.org wrote:

> thanks a lot for your replies, now i know what is gimbal lock and
> that the pasted code solve it, so know euler transformation/
> rotation is the same like the matrix-multiplication...
>
> first we have one problem and two approaches
> now we've reduce the euler "approach" to matrix-approach,
> but the problem is still unsolved...
> ---
> [Message sent by forum member 'bennidd' (sven)]
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
> For additional commands, e-mail: interest-help@java3d.dev.java.net
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net

bennidd
Offline
Joined: 2006-02-14

[..] Oh, I get by with a little help from my friends [..] beatles 1967 :-)

through the replies and the help from a friend i see the things a little bit more clearly.

at first there was a fault done by me:
if i do my rotation by multiply rotX(angleX).rotY(angleY).rotZ(angleZ) only the first rotation will be done as a visibly right (right with the respect to my intended rotation) rotation (visibly as rotation around the local x-axis) - even assuming that the rotation around the x-axis is the first rotation.
But my calculation through accumulating the angles will never solve my problem/my intended rotation, because the rotations have to be always made around the axis i selected by the key-pressed (in other words: if i want to rotate around the y-axis at last i can't rotate around the z-axis at last): the solution is not to accumulate the angles, but the rotation:
[i]
Transform3D currentRotation = new Transform3D();
if (code == 39)
currentRotation.rotY( Math.PI/FACTOR);
else if (code == 37)
currentRotation.rotY(-Math.PI/FACTOR);
else if (code == 40)
currentRotation.rotX( Math.PI/FACTOR);
else if (code == 38)
currentRotation.rotX(-Math.PI/FACTOR);
else if (code == 33)
currentRotation.rotZ( Math.PI/FACTOR);
else if (code == 34)
currentRotation.rotZ(-Math.PI/FACTOR);
//accumulate the rotation
rotation.mul(currentRotation);
[/i]

so my conclusion is:

1. if i done rX = rotX(x); rY = rotY(y); rZ = rotZ(z); r.set(identMatrix); r.mul(rX); r.mul(rY); r.mul(rZ); the first rotation is done global and that is (i didn't understand why...) the z-rotation -> with this i can explain the visual behavior (see http://rcswww.urz.tu-dresden.de/~s8400000/local_vs_global.pdf)

2. my first solution would never work (even if axes transformated too resp. even if local rotation is done and the multiplication is in the write order) because matrix mult. isn't commutativ (surprise, surprise...)

3. rotation can be done: global or locally and accumulativ or in rotX-rotY-rotZ-steps -> three different transformations/rotations
__a) global and accumulativ: every rotation applies to
_____the global axes; every rotation is done in order

__b) global and 3-steps: every rotation applies to
_____the global axes; 1. around x, 2. around y
_____ -> "a) = b)"

__c) local and accumulativ: every rotation is based on
_____further rotations;

__d) local and 3-steps: one rotation is done like global,
_____second based on first, third based on first and sec.

ok, now a part of my initial 1. question is solved and the whole 2. question - nearly everything is fine, but there is sth. that still remains:

Why the order of (global) rotation is reversed?

@John Steel:
> This is because the operations are really a "similarity transform".
> Your matrix multiplies will need to mimic this sequence.
Sorry, i didn't understand the reason - please could u tell me in other words, may by an example?

Sven

messengers
Offline
Joined: 2004-04-18

(If I understand the question correctly:)
These matrix ops are not commutative. They do not work the same, do not give the same result, if the operations are applied in reverse or other orders.
regards s

nachiket_patel
Offline
Joined: 2007-02-03

please, help me... i m stuck.

i have one Vector3f of my ViewPlatform and another Vector3f where my Shape3D is placed.

now i have one textbox where i search for object and i have stored string in my Shape3D userData. so i search it and i can find out objects Vector..

now heres my problem..how to rotate camara along with (x,y,z) all axis.. so it aims (lookAt) shape3d's Vector3f?

varniot
Offline
Joined: 2006-02-17

Hello!

I've been reading this topic you talked about during September and I've got a problem related with it.

Â¿Is there a difference between rotating an object about the objects axis or rotating that object about the world axis? I can't know when the rotation I'm doing is related to the object axes or the world axes.

Thank you!

messengers
Offline
Joined: 2004-04-18

>Â¿Is there a difference between rotating an object about the objects axis or rotating that object about the world axis?

yes. With one object in a scene you have two 3D co-ordinate systems to deal with - local co-ordinates for the object and world co-ordinates for the view.
javax.media.j3d.ViewPlatform
"The ViewPlatform leaf node object controls the position, orientation and scale of the viewer. It is the node in the scene graph that a View object connects to. A viewer navigates through the virtual universe by changing the transform in the scene graph hierarchy above the ViewPlatform."
To change the local position, orientation and scale of an object write to the transform parent of the object.

>I can't know when the rotation I'm doing is related to the object axes or the world axes.

It depends upon which transform you write to.

Hope helps
regards

varniot
Offline
Joined: 2006-02-17

I think I didn't explain my question correctly.

I'm not talking about modifying the ViewPlatform's transform. If I modify this transform, all the universe will move. I only want to rotate an object (but not all the universe or the view).

I'll try to explain it again:

Imagine a cube in the middle of the universe. The same cube we can see in the application java3d.jar from the first post. The cube has its own axes and the world has the X, Y and Z axes too.

When you rotate an object, you can consider the rotation about the cube axes or the world axes.

An example with the application in the first post:

At first, the cube axes and the world axes are parallel.

- Push left key twice: The cube will rotate 45Âº about the Y axis (the vertical axis). We see that the axes in the cube rotate with the cube.

Without selecting Euler:

- Push up (or down) key: the cube will rotate about the world X axis.

Selecting Euler:

- Push up (or down) key: the cube will rotate about the cube X axis, as the object X axis have changed (only the cube Y axis is parallel with the world Y axis, the other axes aren't parallel), the rotation will be different than in the previous situation (without selecting Euler).

In my application I've got three parallels views (front, top and left) and the rotations in front and top views are about the object axes and the rotations in the left view are about the world axes.

I hope I was able to explain my problem now. Thanks!

messengers
Offline
Joined: 2004-04-18

I don`t really understand the question but if you want to set the matrix in a Transform3D to some co-ordinates you can use javax.vecmath.AxisAngle4d
regards

messengers
Offline
Joined: 2004-04-18

There was a thread called robot arm simulations that included this code. It might help, because it may be that you need to use quaternions instead of eulers?
:-)s

[code]
/*
public final Quat4f createQuaternionFromAxisAndAngle(
float x, float y, float z, float angle )
{
float sin_a = (float) Math.sin( angle * 0.5f );
float cos_a = (float) Math.cos( angle * 0.5f );

x = (float) (x * sin_a);
y = (float) (y * sin_a);
z = (float) (z * sin_a);
float w = (float) cos_a;

return new Quat4f(x,y,z,w);
}

public Vector3f createEulerfromQuat(Quat4f quat)
{

return new Vector3f();
}

private final Quat4f createQuaternionFromEuler( float
angleX, float angleY, float angleZ )
{
//simply call createQuaternionFromAxisAndAngle for
each axis
//and multiply the results
Quat4f qx = createQuaternionFromAxisAndAngle(
1f,0f,0f, angleX );
Quat4f qy = createQuaternionFromAxisAndAngle(
0f,1f,0f, angleY );
Quat4f qz = createQuaternionFromAxisAndAngle(
0f,0f,1f, angleZ );

//qx = qx * qy
qx.mul( qy );

//qx = qx * qz
qx.mul( qz );

return qx;
}
//This is all help I can give.
//God Bless you.
//Alessandro
[/code]

messengers
Offline
Joined: 2004-04-18

http://www.gamedev.net/reference/articles/article877.asp
regards s

bennidd
Offline
Joined: 2006-02-14

thanks, i also try it to use "private" (the same like in the article) rotation-matrices for x, y, z but it comes up in the same result of the default ones (rotX, rotY, rotZ).
So the matrices are not the problem...

Sven

Christophe LOREK

are you aware of what gimbal lock is ?

http://en.wikipedia.org/wiki/Gimbal_lock

----- Original Message -----
From:
To:
Sent: Friday, September 16, 2005 10:25 AM
Subject: Re: Rotation in java 3d - diffs between setEuler, rotX, Y, Z etc.

> thanks, i also try it to use "private" (the same like in the article)
rotation-matrices for x, y, z but it comes up in the same result of the
default ones (rotX, rotY, rotZ).
> So the matrices are not the problem...
>
> Sven
> ---
> [Message sent by forum member 'bennidd' (sven)]
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
> For additional commands, e-mail: interest-help@java3d.dev.java.net
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net

bennidd
Offline
Joined: 2006-02-14

i think gimbal lock is a mechanical problem
but here there is only maths...

but maybe i'm wrong, so please tell me how u would solve this problem (may by presenting the right matrix)...

Sven

vtan
Offline
Joined: 2005-09-21

I am experiencing a similar problem, which has left me very confused. Basically I want to align a cone (or many cones) to a tangentVector in 3d space. The vector has a start point and an end point and the tangent vector can be found by

tangentVector = endPoint - startPoint;

Hence I get the three angles between this vector and the basis vectors by doing

angleX = tangentVector.angle(new Vector3d(1.0d, 0.0d, 0.0d));
angleY = tangentVector.angle(new Vector3d(0.0d, 1.0d, 0.0d));
angleZ = tangentVector.angle(new Vector3d(0.0d, 0.0d, 1.0d));

Then I create a Transform3D object t3D and use the setEuler method

t3D.setEuler(angleX, angleY, angleZ)
TransformGroup tgRotate = new TransformGroup(t3D);

I have taken the translation (which works fine) into account too.

But the rotation is still not working i.e. the cone is still not aligned with the tangent vector in space.

Thank you.
Vincent Tan

bennidd
Offline
Joined: 2006-02-14

if it is to simple, just please give me a hint (link) were i can read the solution...

otherwise: if java3d "crashes" in such simple issue - how it will be ever established as a 3d webformat?

nikolai
Offline
Joined: 2003-06-10

a)the rotX*rotY*rotZ rotate only around the z-axis correctly

if you do like this:

trans.rotX(x);
trans.rotY(y);
trans.rotZ(z);

Then only the rotation around Z will take effect.

To rotate all 3 you must do this:

transx.rotX(x);
transy.rotY(y);
transz.rotZ(z);
trans.mul(transx);
trans.mul(transy);
trans.mul(transz);

But beware the order you do this in is very important, careful consider which axis order to rotate.

vtan
Offline
Joined: 2005-09-21

I have some relevant experience with regard to this problem. I realized that for my application trans.setEuler(x,y,z) method is similar to the following code segment that Nikolai suggested.

transx.rotX(x);
transy.rotY(y);
transz.rotZ(z);
trans.mul(transx);
trans.mul(transy);
trans.mul(transz);

Make sure you get the x, y, z angles correctly i.e. axes are aligned.

Kind regards,
Vincent

bennidd
Offline
Joined: 2006-02-14

at first, thanks for your replies!

@Nikolai:
i do the following:
Vector3d vec = new Vector3d(new
double[]{angleX, angleY, angleZ});
euler.setEuler(vec);
Matrix4d m = new Matrix4d();
m.setIdentity();
rotation.set(m);
if (!HelloJava3Da.chEuler()){
rotationX.rotX(angleX);
rotationY.rotY(angleY);
rotationZ.rotZ(angleZ);
rotation.mul(rotationX);
rotation.mul(rotationY);
rotation.mul(rotationZ);
} else
rotation.mul(euler);
targetTG.setTransform(rotation);

the rotation is done in the SimpleBehaviour class

@Vincent:
> [..] setEuler() [..] similar to the follow [..]
similar but NOT equal: if u try my program an do a change on every axis (e.g. one click CursorDown, CursorLeft and one PageDown) u see the difference (if u enable/disable Euler u have to update the painting by clicking in the e.g. black background and pressing space - quite uncomfortable i know ... :-)).

> [..] axes are aligned [..]
angleX, angleY, angleZ are sums of fractional pi
or what u mean by "aligned"

may i first restrict on the matrix multiplication:
at first the axes of the java3d universe are set
y- |_ -x
z- /
so that the z-axis is visible for me just as a point
if the rotation is done without changing the universe axes, so i should see on
- x-axis rot. that my cube rotate up and down
- y-axis rot. that my cube rotate left and right
- z-axis rot. that my cube rotate in a "circle"
but what i see is:
- x-axis rot. that my cube rotate up and down
- y-axis rot. that my cube rotate left and right
- z-axis rot. that my cube rotate around his "z-axis" of my cube

if the rotation is done with transforming the axes, so i should see (thats what i want) on
- x-axis rot. that my cube rotate around his "x-axis"
- y-axis rot. that my cube rotate around his "y-axis"
- z-axis rot. that my cube rotate around his "z-axis"

the questions is why rotation (done by the matrix-mul.) doesn't follows the hypothetical manner

greetings to singapore and denmark
sven