4

I have some object in world space, let's say at (0,0,0) and want to rotate it to face (10,10,10).

How do i do this using quaternions?

philkark
  • 2,417
  • 7
  • 38
  • 59
PeeS
  • 1,164
  • 3
  • 20
  • 43
  • 1
    Are you asking about the math behind Quaternion rotations or how to implement it? If you understand how quaternions work, implementing them in C++ is pretty simple and depending on if this is a one time thing or not, can be done in a few lines of mathy code. If you don't understand quaternions, this is in the wrong place – im so confused Oct 22 '12 at 15:51
  • @AK4749 - Hi, i'm asking abouth the math that stands behind the scenes here. Having two Vector3, where (1) is the object postition and (2) is the position i want this object to rotate to - how do i calculate the quaternion that will represent this rotation ? – PeeS Oct 22 '12 at 16:13
  • Quaternion are good at interpolating between matrices not vectors. You'll need at least two sets of two vectors (the position + the direction) to build two matrices (ie. position + rotation).You then convert theses matrices to quaternions, interpolate beetwen them, and convert back to matrices. – user18428 Oct 22 '12 at 16:37
  • @user1654209 that's only half useful. While I personally believe quaternions are better suited for homogenous transforms and the like as opposed to euler angles, it is not true that you need to do what you mentioned to derive a quaternion that would produce a given result. – im so confused Oct 22 '12 at 16:42
  • @PeeS see my answer for pseudocode that should leave the math pretty understandable yet provide a starting point for your code – im so confused Oct 22 '12 at 16:43
  • @AK4749 : Could you expand please? How do you relate your answer to rotation?The comment I made is derived from typical usage of quaternions in camera animations... – user18428 Oct 22 '12 at 16:47
  • @user1654209 while this should probably be in chat, here's a little bit that may satisfy you - First of all, unit quaternions can be thought of *as* rotations. They cover the SO(3) group, which I'm sure you're familiar with as 3x3 rotation matrices, another set that covers SO(3) - a rotation group of operations. As such, it is best to think of a quaternion as a rotation (i,j,k components), with an optional scalar component (1 component) when visualizing quaternions for this purpose – im so confused Oct 22 '12 at 16:56
  • @user1654209 this ( http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation ) will answer many questions you might have – im so confused Oct 22 '12 at 16:56
  • @user1654209 so to directly answer your question, my answer answers his question in that he/she requires "the" quaternion that represents the rotation performed to convert one vector to another. The algorithm I provided produces a (the?) quaternion that satisfies this requirement. – im so confused Oct 22 '12 at 17:03
  • 1
    Thanks but i need no quaternion course from Wikipedia :)My concern was about you finding my comment half usefull I just wanted to know why. – user18428 Oct 22 '12 at 17:03
  • possible duplicate of [Finding quaternion representing the rotation from one vector to another](http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another) – Mason Wheeler Oct 23 '12 at 21:38

4 Answers4

8

This question doesn't quite make sense. You said that you want an object to "face" a specific point, but that doesn't give enough information.

First, what does it mean to face that direction? In OpenGL, it means that the -z axis in the local reference frame is aligned with the specified direction in some external reference frame. In order to make this alignment happen, we need to know what direction the relevant axis of the object is currently "facing".

However, that still doesn't define a unique transformation. Even if you know what direction to make the -z axis point, the object is still free to spin around that axis. This is why the function gluLookAt() requires that you provide an 'at' direction and an 'up' direction.

The next thing that we need to know is what format does the end-result need to be in? The orientation of an object is often stored in quaternion format. However, if you want to graphically rotate the object, then you might need a rotation matrix.

So let's make a few assumptions. I'll assume that your object is centered at the world's point c and has the default alignment. I.e., the object's x, y, and z axes are aligned with the world's x, y, and z axes. This means that the orientation of the object, relative to the world, can be represented as the identity matrix, or the identity quaternion: [1 0 0 0] (using the quaternion convention where w comes first).

If you want the shortest rotation that will align the object's -z axis with point p:=[p.x p.y p.z], then you will rotate by φ around axis a. Now we'll find those values. First we find axis a by normalizing the vector p-c and then taking the cross-product with the unit-length -z vector and then normalizing again:

a = normalize( crossProduct(-z, normalize(p-c) ) );

The shortest angle between those two unit vectors found by taking the inverse cosine of their dot-product:

φ = acos( dotProduct(-z, normalize(p-c) ));

Unfortunately, this is a measure of the absolute value of the angle formed by the two vectors. We need to figure out if it's positive or negative when rotating around a. There must be a more elegant way, but the first way that comes to mind is to find a third axis, perpendicular to both a and -z and then take the sign from its dot-product with our target axis. Vis:

b = crossProduct(a, -z );

if ( dotProduct(b, normalize(p-c) )<0 ) φ = -φ;

Once we have our axis and angle, turning it into a quaternion is easy:

q = [cos(φ/2) sin(φ/2)a];

This new quaternion represents the new orientation of the object. It can be converted into a matrix for rendering purposes, or you can use it to directly rotate the object's vertices, if desired, using the rules of quaternion multiplication.

JCooper
  • 6,395
  • 1
  • 25
  • 31
1

An example of calculating the Quaternion that represents the rotation between two vectors can be found in the OGRE source code for the Ogre::Vector3 class.

Will
  • 4,585
  • 1
  • 26
  • 48
1

In response to your clarification and to just answer this, I've shamelessly copied a very interesting and neat algorithm for finding the quat between two vectors that looks like I have never seen before from here. Mathematically, it seems valid, and since your question is about the mathematics behind it, I'm sure you'll be able to convert this pseudocode into C++.

quaternion q;
vector3 c = cross(v1,v2);
q.v = c;
if ( vectors are known to be unit length ) {
    q.w = 1 + dot(v1,v2);
} else {
    q.w = sqrt(v1.length_squared() * v2.length_squared()) + dot(v1,v2);
}
q.normalize();
return q;

Let me know if you need help clarifying any bits of that pseudocode. Should be straightforward though.

dot(a,b) = a1*b1 + a2*b2 + ... + an*bn

and

cross(a,b) = well, the cross product. it's annoying to type out and
can be found anywhere.
im so confused
  • 2,091
  • 1
  • 16
  • 25
  • 1
    Thank You, for your explanation. My issue has been solved, thanks to both Your description and JCooper's. – PeeS Oct 22 '12 at 18:38
0

You may want to use SLERP (Spherical Linear Interpolation). See this article for reference on how to do it in c++

user18428
  • 1,216
  • 11
  • 17