Sign in to follow this  
jpmcmu

Rotation Problem

Recommended Posts

jpmcmu    184
I am trying to rotate an object toward a location in space. I have the math for rotating one vector towards another down just fine, and it all works. However, when I multiple the resulting rotation on to the matrix stack, the resulting rotation is not what I expected. The rotations come out as a left-handed rotation and what seems to be local rotations. The object is original facing the -z axis (0.0,0.0,-1.0). I rotate the object to face the positive y axis (0.0,1.0,0.0). The heading vector says its facing the positive y axis but the object ends up facing the -y axis. If I then rotate it to face the negative x axis the object ends up rotating around the y axis, but the heading vector ends up facing the correct position. Any help would be greatly appreciated. Create rotation to turn one vector into another
// TODO: needs optimizing 
quaternion::quaternion(const vec3d& from, const vec3d& to)
{
	vec3d current = from;
	vec3d target = to;
	
	target.normalize();
	current.normalize();
	
	double angle = acos( current.dot(target) ) * TO_DEGREES;
	vec3d axis = current.cross(target);
	
	if ( fabs(angle) <= 0.00001)
	{
		*this = quaternion();
		return;
	}
	
	if ( fabs(angle -180.0) <= 0.00001 )
	{
		vec3d temp;
		if( fabs(from.i) < fabs(from.j) )
		{
			if( fabs(from.i) < fabs(from.k) )
				temp.set(1.0,0.0,0.0);
			else
				temp.set(0.0,0.0,1.0);
		}
		else if( fabs( from.j) < fabs(from.k) )
			temp.set(0.0,1.0,0.0);
		else
			temp.set(0.0,0.0,1.0);
			
		axis = from.cross(temp);
	}
	
	*this = quaternion(angle,axis);
}

Quaternion to matrix code
matrix quaternion::toMatrix() const
{
	matrix _matrix;
	
	// Pre-compute quat combinations
	double xw = _quat[1]*_quat[0],
		   xx = _quat[1]*_quat[1],
	       xy = _quat[1]*_quat[2],
	       xz = _quat[1]*_quat[3],
	       
	       yw = _quat[2]*_quat[0],
	       yy = _quat[2]*_quat[2],
	       yz = _quat[2]*_quat[3],
	       
	       zw = _quat[3]*_quat[0],
	       zz = _quat[3]*_quat[3];
	
	// Apply quat combinations
	_matrix[0] = 1.0-2.0*(yy + zz);
	_matrix[1] = 2.0*(xy - zw);
	_matrix[2] = 2.0*(xz + yw);
	_matrix[3] = 0.0;
	_matrix[4] = 2.0*(xy + zw);
	_matrix[5] = 1.0-2.0*(xx + zz);
	_matrix[6] = 2.0*(yz - xw);
	_matrix[7] = 0.0;
	_matrix[8] = 2.0*(xz - yw);
	_matrix[9] = 2.0*(yz + xw);
	_matrix[10] =1.0 -2.0*(xx + yy);
	_matrix[11] = 0.0;
	_matrix[12] = 0.0;
	_matrix[13] = 0.0;
	_matrix[14] = 0.0;
	_matrix[15] = 1.0;
	
	return _matrix;
}

What I do with the code above
_rotation = quaternion(heading,target) * _rotation;

glPushMatrix();
glMultMatrixd( _rotation.toMatrix() );
glPopMatrix();

Share this post


Link to post
Share on other sites
alvaro    21266
It looks to me like you want to do
_rotation = _rotation * quaternion(heading,target);


EDIT: If that doesn't fix your problem, I suggest you run it through a debugger and check the intermediate results. You can also simply add a bunch of print statements while you debug the problem.

[Edited by - alvaro on December 19, 2008 10:24:02 AM]

Share this post


Link to post
Share on other sites
jpmcmu    184
Thanks for the reply. _rotation is a quaternion, and quaternion multiplication is not commutative so it should be _rotation = new_quat * _old_quat; I have been running through a debugger and the resulting rotation is correct. When I rotate a vector with the resulting rotation it faces the point I want.

I just can't seem to find out why the object in the game is not rotated correctly. As far as I can tell the toMatrix() code is correct. Since the rotation can rotate a heading vector towards the correct position, doesn't this mean that the same rotation can rotate an object towards that point? Instead of converting the quaternion to a matrix should I be using it to rotate heading, up, and right vectors and then create a matrix from those? I guess ill try this later, off to work.. hobbies don't pay bills..

Share this post


Link to post
Share on other sites
alvaro    21266
Quote:
Original post by jpmcmu
Thanks for the reply. _rotation is a quaternion, and quaternion multiplication is not commutative so it should be _rotation = new_quat * _old_quat; I have been running through a debugger and the resulting rotation is correct. When I rotate a vector with the resulting rotation it faces the point I want.


I just can't seem to find out why the object in the game is not rotated correctly.

So what you are saying is that your problem is that you have a quaternion that represents some rotation, but when you try to use it to set up the matrix in OpenGL, the object is not displayed the way you want it. In that case you should concentrate on that problem, and not complicate matters telling us about how you are composing rotations to make the object look somewhere.

You should be able to rotate each individual vertex using the quaternion, or have OpenGL do the rotations for you, and get the same results. I would try to make a simple program that does just that; if there is something about setting up the matrix stack in OpenGL that you don't understand, writing this simple program will help you identify what it is and fix it.

Share this post


Link to post
Share on other sites
swiftcoder    18437
Quote:
Original post by jpmcmu
Instead of converting the quaternion to a matrix should I be using it to rotate heading, up, and right vectors and then create a matrix from those?
Try writing a test program that transforms a vector by your quaternion, and then transforms a vector by the matrix, and compares the results.

Share this post


Link to post
Share on other sites
jpmcmu    184
I implemented a different method to convert to the quaternion to a matrix and that solved the problem. The above code works but it results in left-handed rotations. I need to figure out why that is later. Anyway, thanks for the help guys.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this