## Quaternion and Rotation Primer in wiki!

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
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
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
Sounds great, I know I could certainly use a deeper understanding (which means, just a tiny bit of it, since right now is pretty much nothing), as well as the math associated with it. A good way to show what math is relevant, and which is not.

Great idea!
regards
discipline
OGRE Community Helper
Posts: 766
Joined: Mon May 16, 2005 12:09 am
Thanks! I appreciate any feedback. Maybe I didn't mention I'm looking for that too.
discipline
OGRE Community Helper
Posts: 766
Joined: Mon May 16, 2005 12:09 am
added section on orientations vs rotations.

I've learned so much writing this article. Now my objects rotate like champs!
joi
Gnome
Posts: 327
Joined: Tue Feb 22, 2005 8:11 pm
Location: brazil
Thats very cool! Thanks for your time on this!
maya 7.0, vs 2005, ogre 1.2
discipline
OGRE Community Helper
Posts: 766
Joined: Mon May 16, 2005 12:09 am
Thanks Joi.

I've linked up the wiki to other pages so it can be found. Consider it released. I've included a link to this thread on the page for article discussion.
skullfire
Gremlin
Posts: 150
Joined: Sat Mar 19, 2005 7:51 pm
Location: San Jose, Costa Rica
Contact:
Ralen
Kobold
Posts: 33
Joined: Sun Jun 19, 2005 6:25 am
A vector describes a line from a given 0,0,0 to another point in 3-space
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?
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
A vector describes a line from a given 0,0,0 to another point in 3-space
it should be 3d-space shouldnt it?
SuprChikn
Bugbear
Posts: 863
Joined: Tue Apr 19, 2005 6:10 am
Location: Melbourne, Aus
Contact:
Ralen wrote:
A vector describes a line from a given 0,0,0 to another point in 3-space
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?
That is the 3D co-ordinate (0,0,0). ie: The point in 3D space defined as having x, y, and z components all equal to 0 (aka the origin).
A vector is used to define direction and distance between two points.
Hmm, hope that isn't too confusing.

Chris Jones wrote:
A vector describes a line from a given 0,0,0 to another point in 3-space
it should be 3d-space shouldnt it?
Yes.
discipline
OGRE Community Helper
Posts: 766
Joined: Mon May 16, 2005 12:09 am
3-space is a lesser used synonym for 3d-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, 77-10). 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:
discipline wrote:A vector is a ray from point A to point B.
I'm not sure "ray" is technically the right word here.
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!
SuprChikn
Bugbear
Posts: 863
Joined: Tue Apr 19, 2005 6:10 am
Location: Melbourne, Aus
Contact:
ah yes, I forgot that line segments don't have a direction as such. They define the connection between two points, but they don't say which way you move (ie: from point A to point B, or B to A).
catalin1976
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
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);
``````
Note: This is only disambigious if no angle is greater than 90 degrees. And only in this case you will get the same values with the getters. (I am not 100% sure on this though)
Anyway a quaternion does not and cannot store the euler angles you used to create it.
team-pantheon programmer
creators of Rastullahs Lockenpracht
catalin1976
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:

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);
``````
input:
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);
``````
same input - same results.
catalin1976
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:

Code: Select all

``````Matrix3 mx;

mx.FromEulerAnglesZYX(Degree(rot.z), Degree(rot.y), Degree(rot.x));

Quaternion q(mx);

_viewport[_selectedViewport]->setCameraRotation(q);
``````
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?
catalin1976
Kobold
Posts: 26
Joined: Wed Jul 20, 2005 11:05 am
Location: Bucharest
Contact:
Problem solved I have found a way to simulate the yaw rotation.
tgraupmann
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.

Code: Select all

``````const Ogre::Quaternion cameraOrientation = m_CameraSceneNode->getOrientation();
Ogre::Vector3 lineOfSight = cameraPosition-(shipPosition-shipOrientation.zAxis()*500);
lineOfSight.normalise();``````
How do I say, hey quat, point at this but keep the same roll?

To be more clear (I want):

Code: Select all

``m_CameraSceneNode->getOrientation().zAxis()``
to equal:

Code: Select all

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

Code: Select all

``````Ogre::Vector3 lineOfSight = cameraPosition-(shipPosition-shipOrientation.zAxis()*500);
lineOfSight.normalise();
Quaternion quat = m_CameraSceneNode->getOrientation().zAxis().getRotationTo(lineOfSight);
m_CameraSceneNode->rotate(quat, Node::TS_PARENT);``````
or written another way:

Code: Select all

``````Ogre::Vector3 lineOfSight = cameraPosition-(shipPosition-shipOrientation.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
You could also use the section titled "Flat XZ Rotation of Objects". Just change XZ to XY.
tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:
The primer has this example:

Code: Select all

`````` Vector3 mDestination = mWalkList.front( );                    // mDestination is the next location
Vector3 mDirection = mDestination - mNode->getPosition();     // B-A = 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);
``````
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...
tgraupmann
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.

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);``````
nim
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!
Gamok
Kobold
Posts: 32
Joined: Tue Oct 10, 2006 7:16 pm
i think its "Theta", used later in the article.