Quaternion for camera, direction problem

Hello,
I’m trying to implement a camera that uses a quaternion to store the orientation.

When I init the camera I calculate the view vector subtracting the interest point from the position point
view = position - interest

then I create my quaternion as
q = view.x, view.y, view.z 0.0

I found this way of setting the quaternion on a website (don’t remember which one), and I’m trying to interpret its meaning.
I think it is an axis-angle representation, but if cos(angle/2) = 0 then angle = PI and this doesn’t really make sense to me.
If you have any idea about this way to set the quaternion, please tell me.

The strange thing is that it actually quite works.
So basically I have my quaternion, every time I change position or interest points I reset the quaternion and everything works fine.

The problem is that I need to retrieve a set of axis to setup things for the camera, I usually need the forward vector (for example to perform a Dolly-like motion, or orbiting), the right and the up vector(to pan and setup opengl camera).

I thought I could get them simply applying the rotation stored in the quaternion to the standard axes for the camera (that is sup = (0,1,0) sright = (1,0,0) and sforward = (0,0,-1)).

So to calculate my set of vectors I do
v’ = Q * v * Q^
where Q^ is the conjugate of Q.

The calculation for the right and up vector seems to work, but if I apply the same to the forward vector I obtain something different from what I started with.
That is
QsforwardQ^ != position - interest

What I really need is to setup a quaternion given a view vector, and then use it to transform the set of starting axis I define.
That is, I need to find a way to setup the quaternion, given a view vector ( Q( viewVector ) )
that satisfy this equation:
QsforwardQ^ == viewVector

I need this in order to be able to setup the camera given a quaternion and the position, because in this way I can just calculate the forward vector and find the interest point at a certain distance.

(I always need an interest point because I want to be able to orbit the camera around it).

I know my knowledge of quaternion is not sufficient, but I’m trying really hard to make things work.

Every help is really appreciated.

Thank you,
Remedios

If you can describe what it is you’re after, in terms of simple Euler angles, then you can set about converting it all to quaternions (which would be trivial to do).

In your previous thread I gave the transformations that will orbit the camera around a pivot (focus point), using only yaw and pitch angles (azimuth and elevation). This is the sort of behavior that you see in many editors. Is this what you had in mind? If so, then your work is done. If, on the other hand, you would like the same behavior with smoothing, such that the camera “chases” the mouse input from the user, then quaternions could be used to interpolate between frames like so:

// Slerp factor or "chase speed" (in [0,1])
float s = 0.25; 

// Distance to keep from pivot
float orbitRadius = 10;
 
// Global quat to hold current orientation
Quaternion g_Q(0,0,0,1);
  
// Temp quat
Quaternion Q(0,0,0,1);
  
// Yaw, pitch transform via axis-angle quats
// Yaw and pitch are updated according to 
// movement of the mouse, for example.
Q *= Quaternion(Vector(0,1,0), yaw);
Q *= Quaternion(Vector(1,0,0), pitch);
 
// Now, slerp from the current orientation
// to this one.
g_Q = slerp( g_Q, Q, s );
 
// Slide out along the +z-axis (default GL 
// forward axis is -z) by orbitRadius, then 
// transform using our new quat.
Vector C = g_Q.transformVector(Vector(0,0,orbitRadius));
  
// Translate to the pivot point in the world
C += pivot;
  
// Move the camera position into camera space
// before we put it in our camera matrix.
C = g_Q.conjugate().transformVector(C);
  
// Convert the current quat to a matrix
Matrix M(g_Q);
  
// Set the translation part of the matrix
M._41 = -C.x; 
M._42 = -C.y; 
M._43 = -C.z;
 
// Load
glLoadMatrixf(&M._11);

The slerp factor, s, is just a percentage of the angle we want to move each frame. It has the effect of making the camera ease into the next orientation. For an elapsed number of frames, f, the slerp angle can be calculated as A = Ao s ^ f, where Ao is the initial slerp angle. You can solve for f: f = -log(Ao) / log(s). This is the number of frames it will take for the slerp angle to reach 1 degree (1, since we can’t take the log of 0). Anyway, you can experiment with different values.

There are other ways to achieve similar results. But this is simple, and the movement is very smooth indeed.