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

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

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

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

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)]

>

> http://www.javadesktop.org/forums/thread.jspa?messageID=113754𛱚

>

> ---------------------------------------------------------------------

> 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

For additional commands, e-mail: interest-help@java3d.dev.java.net

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

(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

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?

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!

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

See tha javadoc for

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

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!

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

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?

hope is helpful

:-)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);

}

// a ser implementado

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]

You may be interested in this article about matrix math

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

regards s

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

are you aware of what gimbal lock is ?

maybe this is your problem

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)]

>

> http://www.javadesktop.org/forums/thread.jspa?messageID=113704𛰨

>

> ---------------------------------------------------------------------

> 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

For additional commands, e-mail: interest-help@java3d.dev.java.net

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

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);

tgRotate.addChild(myCone);

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

tgTranslate.addChild(tgRotate);

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

Please advise.

Thank you.

Vincent Tan

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?

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.

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

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

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

search a bit on google for more infos, a quick summary :

"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)]

>

> http://www.javadesktop.org/forums/thread.jspa?messageID=113720𛰸

>

> ---------------------------------------------------------------------

> 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

For additional commands, e-mail: interest-help@java3d.dev.java.net