Jump to content
  • Advertisement
Sign in to follow this  
jon723

Is this the correct way to orient myself with quaternions??

This topic is 4456 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a Quaternion class with a function: Quaternion rotate(float angle, float x, float y, float z) // this is overloaded for Vectors too { w = cos(angle/2); myX = x*sin(angle/2); myY = y*sin(angle/2); myZ = z*sin(angle/2); return *this; } When I want to rotate myself around my position is this the correct way to go about it (assume I have a quaternion representing my orientation 'myOrien' and a vector for my position 'myPos'): myOrien = myOrien.rotate(45, 0,1,0) * Quaternion(0, myPos) * ~myOrien; // the '~' is my conjugate operator Thank you, Jon

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by jon723
myOrien = myOrien.rotate(45, 0,1,0) * Quaternion(0, myPos) * ~myOrien; // the '~' is my conjugate operator
Assuming that when operator~() is called, myOrien has the values assigned to it by the previous call to rotate(), then this will rotate the point 'myPos' with respect to the origin; in other words, it will cause your object to 'orbit' about (0, 0, 0).

I'm guessing this isn't what you want. If you want your object's orientation to change, recompute its quaternion via local or global rotations as appropriate; if you want your object's position to change, update it via the method of your choice (physics simulation, or perhaps just adding constant multiples of the direction vectors); to interface with an API or with other matrix operations, load the position and orientation into the proper class (probably a 4x4 matrix).

That's all assuming that I understood correctly what you're wanting to do.

Share this post


Link to post
Share on other sites
Yea the final step to all of this would be to convert the quaternion to a matrix and load that matrix (im using opengl). What im trying to accomplish is rotation around an axis "local" to my position. I understand why it would rotate globally but how would i go about doing this locally?? Would the same functions apply??


EDIT:

myOrien = myOrien * myOrien.rotate(45, 0,1,0);

Would that be the proper way to rotate myself locally??

[Edited by - jon723 on May 9, 2006 11:01:10 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by jon723
myOrien = myOrien * myOrien.rotate(45, 0,1,0);

Would that be the proper way to rotate myself locally??
Yes, it should be either that or the other way around (depending on your chosen convention for quaternion mult order).

Share this post


Link to post
Share on other sites
There are a few things that need to be addressed:
  • Rather than using a function named rotate to intialize a quaternion, you should use a constructor. However, since you already have a constructor that takes 4 floats, you need another signature for axis/angle.
  • While this might work, it has problems:
        myOrien = myOrien.rotate(45, 0,1,0) * Quaternion(0, myPos) * ~myOrien; 
    rotate() must be called before operator~() is called. Otherwise, it won't work right. Also, reusing the variable myOrien is confusing.
  • Finally, C++ math functions use radians, not degrees. Replace 45 with M_PI/4 or something like that.
Here is how I would change the code:
    Quaternion::Quaternion( float angle, Vector3 const & axis )
{
w = cos(angle/2);
x = axis.x * sin(angle/2);
y = axis.y * sin(angle/2);
z = axis.z * sin(angle/2);
}
...
Quaternion orientation( M_PI/4, Vector3(0,1,0) );
new_position = orientation * Quaternion(0, myPos) * ~orientation;

Share this post


Link to post
Share on other sites
Creating a new Quaternion each time I want to rotate seems like overkill to me. The internals of my rotation function do all of that already and since the rotation function returns a quaternion it saves me the trouble of having to declare a new variable each time I want to use it.

Share this post


Link to post
Share on other sites
Quote:
Original post by jon723
Creating a new Quaternion each time I want to rotate seems like overkill to me.
If you mean in terms of performance, don't worry about it; creating a temporary quaternion or two in the course of orienting your camera is of almost no consequence.

If you mean in terms of clarity or functionality, it depends. Your first example, while probably ok due to C++ operator precedence and associativity, is confusing and generally bad practice. Also, 'rotate' is not a particularly good name for that function; it should be a constructor as John suggested, or perhaps something like 'fromAxisAngle()'.

Share this post


Link to post
Share on other sites
Given an object that you want to rotate by sigma around axis A, where axis A is in object-local coordinates, right-sided multiplication:

(ie, ABCx means apply C to x, then B to Cx, then A to BCx).


Quaternion Rotation( double radians ); // generates a Quaternion that rotates points around the z-axis.

Quaternion Axis( Vector3D v ); // Axis(v)*(0,0,1) = v

Quaternion RotateOrientation( Quaternion current, Quaternion Axis, double radians ) {
return current*Axis*Rotation(radians)*~Axis*~current;
}

Quaternion RotateOrientation( Quaternion current, Vector3D Axis_, double radians ) {
return RotateOrientation( current, Rotation(Axis_), radians );
}


You might want an axis that isn't rooted at (0,0,0). To do this, you have to add another parameter.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!