Rotation by quarterions or matrixes?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Spartak

Rotation by quarterions or matrixes?

Post by Spartak »

Somebody can help me to rotate node around vector? Should I use It is not clear in Irrlicht.
Baal Cadar
Posts: 377
Joined: Fri Oct 28, 2005 10:28 am
Contact:

Post by Baal Cadar »

What does "around vector" mean? as an axis?

Code: Select all

vector3df myaxis;
float myangle;
vector3df myrotation;
quaternion q;

q.fromAngleAxis(myangle, myaxis);
q.toEuler(myrotation);

mynode->setRotation(myrotation);
If this is not what you want, put more effort into phrasing a question.

As an aside, I really wonder if the quaternion class is actively used. The interface ist uncomfortable, inconsistent and lacking.
Spartak

Post by Spartak »

Thank you Baal! You did understand well. I have a node and I want to rotate it around my axis A(0.5, 0.5, 0.5).
1.Should my axis be "normalized vector of length =1"?
2.Should I move my node to 0,0,0 before rotation?
3.Why when I try
vector3df myaxis = core::vector3df( 0, 1, 0);
float myangle = 45;
the rotation that I see is very small?

I have read that quaternion is the better way for rotation then eulers angles and matrixes, but irrlicht has no examples for any way of rotation! In the forum I have read that a lot of users use for rotation newton and ect. because in irrlicht it is too complicated.
Baal Cadar
Posts: 377
Joined: Fri Oct 28, 2005 10:28 am
Contact:

Post by Baal Cadar »

Spartak wrote: 1.Should my axis be "normalized vector of length =1"?
Yes, the axis has to be normalised.
Spartak wrote: 2.Should I move my node to 0,0,0 before rotation?
Don't think so. This should be done by Irrlicht internally, if it applies transforms in the standard order: scale -> rotation -> translation. Not 100% sure, you could look it up in the source or just experiment a bit. Though if you want to rotate the node around its local coordinate systems origin independently from the translation, you need to introduce an intermediate IDummyTransformationSceneNode. See API docs for how to use it.
Spartak wrote: 3.Why when I try
vector3df myaxis = core::vector3df( 0, 1, 0);
float myangle = 45;
the rotation that I see is very small?
Because the angle is not given in degree, but in radian. Convert it to radian and it should work. radian = degree*PI/180.0f
Spartak wrote: I have read that quaternion is the better way for rotation then eulers angles and matrixes, but irrlicht has no examples for any way of rotation! In the forum I have read that a lot of users use for rotation newton and ect. because in irrlicht it is too complicated.
It is true, that matrix and quaternion are both better suited than euler angles. Euler angles have an inherent flaw, the so called gimbal lock. With certain angles, a degree of freedom is lost and thus some rotations can not be expressed by euler angles when applied in a strict order, like it is done in Irrlicht. Also doing calculations with euler angles is awkward.
Whether matrices or quaternions are better is debatable, though quaternions have a slight advantage overall, imho.

Btw, doing calculation with quaternions and then applying the result as euler angles to the node, does not prevent the gimbal lock problem. I don't know an easy way to work around this. I'd be happy if someone could point it out. :)
Spartak

Post by Spartak »

In order to prevent "gimbal lock" in eulers angels I use matrixes:

void RotateNode(scene::ISceneNode *node, vector3df aIVectorDeg)
{
vector3df lIVec = node->getRotation(); //get current rotation (euler)
matrix4 lmxFirst;

lmxFirst.setRotationDegrees(lIVec);//set firsth matrix to current rotation

matrix4 lmxSecond;
lmxSecond.setRotationDegrees(aIVectorDeg); //set second matrix

lmxFirst *= lmxSecond; //multipy them

lIVec = lmxFirst.getRotationDegrees();//get rotation vector from matrix(euler)
node->setRotation(lIVec);//rotate node
}
Spartak

Post by Spartak »

I think you should use quaternion composition for rotation something like this:


code:

const irr::f64 GRAD_PI = 180.0 / 3.14159;
core::vector3df Target;

core::vector3df CurrAngels = node->getRotation();
// current rotation of the node in eulers angels

core::quaternion QStart(CurrAngels .X , CurrAngels.Y , CurrAngels.Z ,1);
// Initial rotation quaternion

core::vector3df Rotation(0.5f, 0.0f, 0.5f);
// Your rotation vector

irr::f64 Degrees = 160.0f / GRAD_PI; // degrees around vector

core::quaternion QRotation(Rotation.X,Rotation.Y,Rotation.Z,Degrees);
// or use QRotation.fromAngleAxis(Rotation)

QStart *= QRotation; // calculate rotation
QStart.toEuler(Target); // store in new vector as Euler rotation for use with irrlight setRotation function

Target *= GRAD_PI; // convert back to degrees

RotateNode(node, core::vector3df(Target.X, 0, 0));
RotateNode(node, core::vector3df( 0, Target.Y, 0));
RotateNode(node, core::vector3df(0, 0, Target.Z));


What do you think about it?
Baal Cadar
Posts: 377
Joined: Fri Oct 28, 2005 10:28 am
Contact:

Post by Baal Cadar »

This doesn't fix the problem. You still end up with an euler angle, you use to set the node rotation. The loss of the degree of freedom can be in it anyway. This is an inherent problem, you can't work around this, without changing the rotation representation in Irrlicht itself. At least I don't see another way.

Your code doesn't work anyway. The 4 float quaternion constructor doesn't take in angel/axis, but the actual components xyzw. So QRotation is not what you expect and it is not even a rotation at all, since it is not of unit length.
Spartak

Post by Spartak »

There are not good news for me. I'm in the middle of project.
When I use your code I can rotate node around "relative" axis. Maybe you know how can I rotate node around "absolute" axis that is not changed after each rotation? Thanks.
Spartak

Post by Spartak »

Im my opinion it works not bad! Try it:

void main()
{
vector3df myaxis = core::vector3df( x, y, z);
float myangle = 77*180/3.14;
vector3df myrotation;
quaternion q;
q.fromAngleAxis(myangle, myaxis);
q.toEuler(myrotation);

RotateNode(point,myrotation);
}

void RotateNode(scene::ISceneNode *node, vector3df aIVectorDeg)
{
vector3df lIVec = node->getRotation(); //get current rotation (euler)
matrix4 lmxFirst;

lmxFirst.setRotationDegrees(lIVec);//set firsth matrix to current rotation

matrix4 lmxSecond;
lmxSecond.setRotationDegrees(aIVectorDeg); //set second matrix

lmxFirst *= lmxSecond; //multipy them

lIVec = lmxFirst.getRotationDegrees();//get rotation vector from matrix(euler)
node->setRotation(lIVec);//rotate node
}

Now I wanna know how can I translate global coordinates to relative coordinates of node. If I will know, I can control rotation of my node!
jreuschel1
Posts: 25
Joined: Sun Nov 12, 2006 7:51 pm
Contact:

Post by jreuschel1 »

maybe this thread applies to your topic


http://irrlicht.sourceforge.net/phpBB2/ ... php?t=4680
Directory of E:\RI-1

00/00/0000 12:00 AM <DIR> .
00/00/0000 12:00 AM <DIR> ..
0 File(s) 0 bytes
2 Dir(s) All bytes free

E:\RI-1>_
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Dude, this thread was 2 years ago... you can't even post as guest anymore.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Dude, this thread was 2 years ago... you can't even post as guest anymore.
You still can post there. If you are registered.

And yes methods used there can be useful to Spartak. They do the same stuff just use matrix instead of quaternion. Irrlicht do use matrix for most if not all of the transformation stuff. Rotations including.
Post Reply