Help, I have some Quaternion problems...

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

Recommended Posts

Hello, thanks for reading my post :) I'm trying to implement a third person camera system featuring azimuth,elevate, and dolly using quaternions. I use gluLookAt() so I have eye, view, and up vectors. I use a parametric vector line to represent my camera system (would this be a good idea?), such that: eye = view + t*u Where view is the view position, t the dolly variable, u is a unit directional vector. At t=1.0 the camera is 1.0 unit away from the object I'm looking at. u is a unit vector generated using quaternion. To generate U I do this: For azimuth I use: Qnew = q*p*conjugate(q) This transforms the quaternion p (representing a point). Where q is defined as q(0,(0,1,0)) So you see I rotate p about the Y axis. For elevate I do the same thing except I rotate p about the viewRight vector. However there is a problem with my elevation code. My camera will not rotate correctly about the viewRight vector unless the camera is directly facing the z axis. I.E instead of elevating straight up it veers to the left or right, it keeps on circling about... So if I azimuth 90 degree, and then elevate by 45 degrees, the rotation is off. Anyone know why? Also do you have to concatnate both the azimuth and elevate quaternions in order to use them? Can you azimuth, then extract the point p, then use elevate again on that point p. Do you have to create an azimuth quat, then an elevate quat, and concat these two and extract the point p? Thanks.

Share on other sites
Before trying to answer and just messing you up, let me ask a couple of questions. 'y' is up; what is considered to be forward, x or z? Also, what is viewRight? Is it a world axis such as x or z, or a local axis computed from your y rotation?

Share on other sites
I'm sorry I was not clear on these things :)

Forward vector is actually the vector I'm rotating. So it is viewForward.

I'm trying to azimuth about the world Y axis (up), elevating about the local viewRight vector.

In the end I use the parametric vector line equation to get the final view and eye to pass to gluLookAt()

I vaguely remeber reading some where using different basis is bad for quaternions.

Share on other sites
Perhaps the viewRight is incorrect.

THe behavior I have seems like that it is not elevating correctly about the right vector.

It is like I'm rotating about a constant right vector, thus the right vector does not reflect the right vector that is normal to both forward and up.

Share on other sites
I have a couple of thoughts but I don't want to jump to conclusions without understanding fully what you're trying to do. Perhaps you could post the relevant code? That is, just the portions pertaining to the problem - the camera rotation code, calculating the viewRight vector, calling gluLookAt(), etc.

Share on other sites
Yes I found the problem!

I was generating the up right vectors using this:

[source lan ="cpp"]/** *This method will recalculate our up and right vectors *We pick and arbitray vector v. *We cross v with _rotPosition to get a vector that is orthgonal to _rotPosition. X axis is a good canadiate. *If v is close to (0,0,0) this means we picked v that is nearly parallel to _foward, we choose another arbitrary vector, y axis is good. *By definition y axis is orthogonal to x axis so we are guaranteed to generate orthogonal vector with _forward. *To get the _right vector we cross v and _forward. *To get up vector we cross _right and _forward */void PerspectiveCamera::recalUpRightVectors(){  MVector3d v(1,0,0);  v = v.crossProduct(_rotPosition);  if(v.dotProduct(v) &lt; M_EPSILON) //bad arbitray vector    {      v.setXYZ(0,1,0);      v = v.crossProduct(_rotPosition);    }  v.normalize();  _right = v.crossProduct(_rotPosition);  _right.normalize();  _up = _right.crossProduct(_rotPosition);  _up.normalize();}

Which I think generates the orthogonal vectors but the right vector is not what I need.

So to fix it I also rotate my view right vector with the same quaternion that I use for the azimuth() method.

[source lan ="cpp"]/**  * This method azimuth the camera by degrees around the focus point. *    * @param double degrees the degree of rotation * @return void **/void PerspectiveCamera::azimuth(double degrees){    //formula to transform a vector quaternion  using quaternion   //about unit axis W is  //q^ = q*p*~q (where ~q is conjugate of q)  degrees *= PIOVER180; //convert to radian  MVector3d focusUp(0,1,0);  double costhetaover2 = cos(degrees/2);  double sinthetaover2 = sin(degrees/2);  MQuaternion q(costhetaover2,focusUp*sinthetaover2);  //_rotPosition.normalize();  MQuaternion p(0,_rotPosition);  MQuaternion q1;  q1.conjugate(q);  MQuaternion ans;   ans.setEqualTo(q*p*q1);  ans.getImaginary(_rotPosition);  //rotate right vector  p.setEqualTo(0,_right);  ans.setEqualTo(q*p*q1);  ans.getImaginary(_right);}

And then I use gluLookAt()

[source lan ="cpp"]/**  * Applies gluLookAt() */void PerspectiveCamera::look(){  //recalUpRightVectors();  //_position.setEqualTo(_position + _dollyVector);  _position.setEqualTo(_focus + _rotPosition*_dollyT);  gluLookAt(_position.v[0], _position.v[1], _position.v[2],	    _focus.v[0], _focus.v[1], _focus.v[2],	                                      0,1,0);	    //_up.v[0], _up.v[1], _up.v[2]);  //_dollyVector.setXYZ(0,0,0);}

I think this fixed the problem. Hope my logic didn't fail me again somewhere lol...

I love this site.

1. 1
2. 2
3. 3
4. 4
Rutin
12
5. 5

• 12
• 16
• 10
• 14
• 10
• Forum Statistics

• Total Topics
632659
• Total Posts
3007692
• Who's Online (See full list)

There are no registered users currently online

×