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 3-space
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 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).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 3-space
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 3d-space shouldnt it?A vector describes a line from a given 0,0,0 to another point in 3-space
- 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.
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:
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-(shipPosition-shipOrientation.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-(shipPosition-shipOrientation.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-(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
-
- 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(); // 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);
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!