Quaternion and Rotation Primer in wiki!
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am
Quaternion and Rotation Primer in wiki!
Finally, I got my objects to rotate properly in Ogre!! To celebrate this success, I decided to write a Quaternion and Rotation Primer in the wiki. It is ready for release to the forums for checking. Then I'll link it up with various pages so it can be found.
Here's what I need:
1) Check my accuracy and understanding, grammar, spelling, etc.
2) Check the clarity of my descriptions.
3) Send me working, concrete code samples that show how to do things with quaternions. For example, I've seen explanations on using slerp in the forums, but no code (haven't looked, nor taken the time to write my own yet). I've also seen discussions on objects walking on the inside and outside of spheres, etc. Provide everything required to run the operation and define each variable.
For the moment, please post corrections, feedback and samples in this thread. I'll compile and organize it all. Then I'll make a public release, link up the wiki page and turn it over.
Quaternion and Rotation Primer
Here's what I need:
1) Check my accuracy and understanding, grammar, spelling, etc.
2) Check the clarity of my descriptions.
3) Send me working, concrete code samples that show how to do things with quaternions. For example, I've seen explanations on using slerp in the forums, but no code (haven't looked, nor taken the time to write my own yet). I've also seen discussions on objects walking on the inside and outside of spheres, etc. Provide everything required to run the operation and define each variable.
For the moment, please post corrections, feedback and samples in this thread. I'll compile and organize it all. Then I'll make a public release, link up the wiki page and turn it over.
Quaternion and Rotation Primer
Last edited by discipline on Fri Jun 17, 2005 1:24 am, edited 1 time in total.
 regress
 Halfling
 Posts: 78
 Joined: Sat Mar 26, 2005 8:39 pm
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am
 skullfire
 Gremlin
 Posts: 150
 Joined: Sat Mar 19, 2005 7:51 pm
 Location: San Jose, Costa Rica
 Contact:

 Kobold
 Posts: 33
 Joined: Sun Jun 19, 2005 6:25 am
Is 0,0,0 the actual coordinate or do you mean x,y,z? As in 0,0,0 can be any combination of x, y or z coordinates?A vector describes a line from a given 0,0,0 to another point in 3space
I want to know what good is a search engine that returns 324,909,188 "matches" to my keyword. That's like saying, "Good news, we've located the product you're looking for. It's on Earth."
 Chris Jones
 Lich
 Posts: 1742
 Joined: Tue Apr 05, 2005 1:11 pm
 Location: Gosport, South England
 x 1
 SuprChikn
 Bugbear
 Posts: 863
 Joined: Tue Apr 19, 2005 6:10 am
 Location: Melbourne, Aus
 Contact:
That is the 3D coordinate (0,0,0). ie: The point in 3D space defined as having x, y, and z components all equal to 0 (aka the origin).Ralen wrote:Is 0,0,0 the actual coordinate or do you mean x,y,z? As in 0,0,0 can be any combination of x, y or z coordinates?A vector describes a line from a given 0,0,0 to another point in 3space
A vector is used to define direction and distance between two points.
Hmm, hope that isn't too confusing.
Yes.Chris Jones wrote:it should be 3dspace shouldnt it?A vector describes a line from a given 0,0,0 to another point in 3space
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am
3space is a lesser used synonym for 3dspace.
A vector is a ray from point A to point B. So really it should look like "A(x1,y1,z1) to B(x2,y2,z2)". However most vectors are assumed to originate from a zero (0,0,0) point. So by convention, we define the vector with only the B coordinate. The reason I say, "a zero point" is because this is relative. The zero point may be the origin of the world, or any other point. The vector only describes the offset from the chosen zero point.
To illustrate using all Vector3s, say a scene node is at (33,55,77) and we attach a camera to it. We can put the camera position at (0,10,10), relative to the scene node. The camera's position relative to the world is actually (0+33, 55+10, 7710). These are two different vectors originating at two different points. However they identify the same point in space.
A vector is a ray from point A to point B. So really it should look like "A(x1,y1,z1) to B(x2,y2,z2)". However most vectors are assumed to originate from a zero (0,0,0) point. So by convention, we define the vector with only the B coordinate. The reason I say, "a zero point" is because this is relative. The zero point may be the origin of the world, or any other point. The vector only describes the offset from the chosen zero point.
To illustrate using all Vector3s, say a scene node is at (33,55,77) and we attach a camera to it. We can put the camera position at (0,10,10), relative to the scene node. The camera's position relative to the world is actually (0+33, 55+10, 7710). These are two different vectors originating at two different points. However they identify the same point in space.
 SuprChikn
 Bugbear
 Posts: 863
 Joined: Tue Apr 19, 2005 6:10 am
 Location: Melbourne, Aus
 Contact:
I'm not sure "ray" is technically the right word here.discipline wrote:A vector is a ray from point A to point B.
The way I learnt it (and I could be wrong here, there may be different definitions in use by different people), a "ray" started at a point and went to infinity in one direction, a "line" goes to infinity in two oposite directions, and a "line segment" goes from one point to another.
If this is the case, then really a vector is a line segment (sorry for being so pedantic).
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am
I used ray because it signifies direction, which is a crucial part of the vector. A segment does not signify direction.
This is a segment: 
This is a vector: >
Perhaps this is a ray: ....>
Really it is a vector, but I have to draw an analogy from somewhere. It is a segmented ray!
This is a segment: 
This is a vector: >
Perhaps this is a ray: ....>
Really it is a vector, but I have to draw an analogy from somewhere. It is a segmented ray!
 SuprChikn
 Bugbear
 Posts: 863
 Joined: Tue Apr 19, 2005 6:10 am
 Location: Melbourne, Aus
 Contact:

 Kobold
 Posts: 26
 Joined: Wed Jul 20, 2005 11:05 am
 Location: Bucharest
 Contact:
Rotation question
Hello!
I have one simple question. I know the rotation around axis X, Y and Z. From those rotation I want to create an Quaternion. Please can some one guide me?
PS:
The functions getPitch() = degree around X (dx), getYaw() = degree around Y (dy), getRoll() = degree around Z (dz). (dx) (dy) and (dz) must be equal with the information used to create the quaternion.
Thank you
I have one simple question. I know the rotation around axis X, Y and Z. From those rotation I want to create an Quaternion. Please can some one guide me?
PS:
The functions getPitch() = degree around X (dx), getYaw() = degree around Y (dy), getRoll() = degree around Z (dz). (dx) (dy) and (dz) must be equal with the information used to create the quaternion.
Thank you
 haffax
 OGRE Retired Moderator
 Posts: 4823
 Joined: Fri Jun 18, 2004 1:40 pm
 Location: Berlin, Germany
 x 7
 Contact:
Code: Select all
Matrix3 mat;
mat.FromEulerAnglesXYZ(pitch, yaw, roll);
Quaternion q(mat);
Anyway a quaternion does not and cannot store the euler angles you used to create it.

 Kobold
 Posts: 26
 Joined: Wed Jul 20, 2005 11:05 am
 Location: Bucharest
 Contact:
Sorry for not posing what I was already tested.
Tested code:
input:
pitch = Degree(10)
yaw = Degree(10)
roll = Degree(10)
results:
pitch = 11.6291
yaw = 7.94708
roll = 11.6921
same input  same results.
Tested code:
Code: Select all
Matrix3 mx;
Quaternion q;
mx.FromEulerAnglesXYZ(Degree(rot.x), Degree(rot.y), Degree(rot.z));
q.FromRotationMatrix(mx);
_viewport[_selectedViewport]>setCameraRotation(q);
pitch = Degree(10)
yaw = Degree(10)
roll = Degree(10)
results:
pitch = 11.6291
yaw = 7.94708
roll = 11.6921
Code: Select all
Quaternion q, qx, qy, qz;
qx.FromAngleAxis(Degree(rot.x), Vector3::UNIT_X);
qy.FromAngleAxis(Degree(rot.y), Vector3::UNIT_Y);
qz.FromAngleAxis(Degree(rot.z), Vector3::UNIT_Z);
q = qx * qy * qz;
_viewport[_selectedViewport]>setCameraRotation(q);

 Kobold
 Posts: 26
 Joined: Wed Jul 20, 2005 11:05 am
 Location: Bucharest
 Contact:
So, after a lot of searching over the internet and a lot of trying I have arived to this:
This code is correct only for the following ranges:
pitch > 179.99 to 179.99
yaw > 89.96 to 89.97
roll > 179.99 to 179.99
This is a stat but I need an algorithm for the entire interval of yaw, any idea?
Code: Select all
Matrix3 mx;
mx.FromEulerAnglesZYX(Degree(rot.z), Degree(rot.y), Degree(rot.x));
Quaternion q(mx);
_viewport[_selectedViewport]>setCameraRotation(q);
pitch > 179.99 to 179.99
yaw > 89.96 to 89.97
roll > 179.99 to 179.99
This is a stat but I need an algorithm for the entire interval of yaw, any idea?

 Kobold
 Posts: 26
 Joined: Wed Jul 20, 2005 11:05 am
 Location: Bucharest
 Contact:

 Gnoll
 Posts: 696
 Joined: Sun Feb 20, 2005 5:28 am
 Contact:
Spent quite a while experiementing and reading the quat primer.
All I want to do is keep the orientation of an existing quat, while just changing the view axis component to point at a new vector.
How do I say, hey quat, point at this but keep the same roll?
To be more clear (I want):
to equal:
Since the two vectors are usually within 30 degrees, I should be able to find the angle between them and rotate the orientation until it matches the second vector.
I'll keep muling over the primer.
Update:
Figured out the answer finally (note the order is important):
or written another way:
All I want to do is keep the orientation of an existing quat, while just changing the view axis component to point at a new vector.
Code: Select all
const Ogre::Quaternion cameraOrientation = m_CameraSceneNode>getOrientation();
Ogre::Vector3 lineOfSight = cameraPosition(shipPositionshipOrientation.zAxis()*500);
lineOfSight.normalise();
To be more clear (I want):
Code: Select all
m_CameraSceneNode>getOrientation().zAxis()
Code: Select all
lineOfSight
I'll keep muling over the primer.
Update:
Figured out the answer finally (note the order is important):
Code: Select all
Ogre::Vector3 lineOfSight = cameraPosition(shipPositionshipOrientation.zAxis()*500);
lineOfSight.normalise();
Quaternion quat = m_CameraSceneNode>getOrientation().zAxis().getRotationTo(lineOfSight);
m_CameraSceneNode>rotate(quat, Node::TS_PARENT);
Code: Select all
Ogre::Vector3 lineOfSight = cameraPosition(shipPositionshipOrientation.zAxis()*500);
lineOfSight.normalise();
Quaternion quat = shipOrientation.zAxis().getRotationTo(lineOfSight);
m_CameraSceneNode>setOrientation(quat*shipOrientation);
Last edited by tgraupmann on Fri Nov 11, 2005 5:57 pm, edited 1 time in total.
 discipline
 OGRE Community Helper
 Posts: 766
 Joined: Mon May 16, 2005 12:09 am

 Gnoll
 Posts: 696
 Joined: Sun Feb 20, 2005 5:28 am
 Contact:
The primer has this example:
Unfortunately, it only works if your node is aligned with this axis. Is there a way to ignore the mNode>getOrientation()>yAxis() plane?
Essentially, it would be useful if an axis in a quaternion could be locked.
I suppose I could always temporarily rotate the node to make it axis aligned Do the calculation. And then rotate it back...
Code: Select all
Vector3 mDestination = mWalkList.front( ); // mDestination is the next location
Vector3 mDirection = mDestination  mNode>getPosition(); // BA = A>B (see vector questions above)
Vector3 src = mNode>getOrientation() * Vector3::UNIT_X; // Orientation from initial direction
src.y = 0; // Ignore pitch difference angle  has to be axis aligned
mDirection.y = 0;
src.normalise();
Real mDistance = mDirection.normalise( ); // Both vectors modified so renormalize them
Quaternion quat = src.getRotationTo(mDirection);
mNode>rotate(quat);
Essentially, it would be useful if an axis in a quaternion could be locked.
I suppose I could always temporarily rotate the node to make it axis aligned Do the calculation. And then rotate it back...

 Gnoll
 Posts: 696
 Joined: Sun Feb 20, 2005 5:28 am
 Contact:
There's an easy way and a hard way. This is an example of the hard way. But it works.
I decided to use our axis dependent solution on an arbitrary axis. To do this, first I needed to rotate to put us back on the axis. Use the axis dependent solution and then rotate back. Walla.
I decided to use our axis dependent solution on an arbitrary axis. To do this, first I needed to rotate to put us back on the axis. Use the axis dependent solution and then rotate back. Walla.
Code: Select all
Ogre::Vector3 lineOfSight = m_Body>getPosition()  m_SelectedTarget>GetPosition();
// We are going to need to rotate this vector to do an axis dependent lookup
Ogre::Vector3 test1 = lineOfSight.normalisedCopy();
Ogre::Quaternion sightOrientation = Ogre::Vector3::UNIT_Z.getRotationTo(test1);
Ogre::Vector3 test2 = sightOrientation.zAxis();
// We need to orient the body so it is axis aligned
Ogre::Quaternion origOrientation = m_Body>getOrientation();
Vector3 test3 = origOrientation.zAxis().normalisedCopy();
Ogre::Quaternion axisOffsetOrientation = Ogre::Vector3::UNIT_Z.getRotationTo(test3);
// We need to apply the orientation to our sight orientation
Ogre::Quaternion oldOrientation = axisOffsetOrientation*origOrientation;
sightOrientation = axisOffsetOrientation*sightOrientation;
// Do the axis dependent lookup
Vector3 src = oldOrientation.zAxis();
src.y = 0; // ignore the y component  has to be axis aligned
src.normalise();
Vector3 dst = sightOrientation.zAxis();
dst.y = 0; // ignore the y component  has to be axis aligned
dst.normalise();
Ogre::Quaternion quat = src.getRotationTo(dst);
// rotate everything back
oldOrientation = axisOffsetOrientation.Inverse() * oldOrientation;
Vector3 test4 = oldOrientation.zAxis().normalisedCopy();
sightOrientation = axisOffsetOrientation.Inverse() * sightOrientation;
Vector3 test5 = sightOrientation.zAxis().normalisedCopy();
// Apply the calculated orientation
oldOrientation = Quaternion::Slerp(Real(_deltaTime*4), oldOrientation, quat*oldOrientation);
// assign the new orientation
m_Body>setOrientation(oldOrientation);

 Gnoblar
 Posts: 22
 Joined: Wed Sep 13, 2006 6:22 am
 Location: Sweden
 Contact:
I haven't read linear algebra or I've forgotten if it's in another course so please clarify abbreviations like the "Th" in "Cos Th". If not an explaination, atleast the full word would be good so I can look it up :)
anyway, great article! I was looking for exactly what it covers for half a day before I found it!
anyway, great article! I was looking for exactly what it covers for half a day before I found it!