Advertisement

Quaternions to other representations

Started by March 19, 2000 11:12 AM
4 comments, last by crazy166 24 years, 11 months ago
how could i take a quaternion i''m using to represent orientation and convert to axis-angle format (i.e. a view vector and roll angle). i followed the gamasutra article on quaternions to move from axis-angle to quaternion, but when i apply the operations in reverse, i get unexpected results. here''s my QuatToAxisAngle function float acw = acos( quat.w ); float sacw = sin( acw ); float isacw = 0.0f; if ( sacw != 0.0f ) { isacw = 1.0f / sacw; } else { //*= not sure what to do here =// } angle = acw * 2.0f; axis.dvX = isacw * quat.x; axis.dvY = isacw * quat.y; axis.dvZ = isacw * quat.z; the problem is, if using the axis-angle to quat code from gamasutra article to construct a quaternion to go into this function, if the roll angle was 0, w = 1 and x,y,z = 0, so i should get (0,0,0), however... no matter what quaternion i feed into this equation, i end up with (0, -1, 0) as my axis and 0 as my angle. something my be wrong with the code that goes from axis-angle to quat as well, since if roll angle is 0, quat ends up the same no matter the view vector. thanks crazy166 some people think i'm crazy, some people know it
I have thought about the same problem (probably from reading the same article too)

This is what I think should be an QuatToAxis function, If the angle is 0, then the axis doesn''t matter.

Note: I have taken out lots of error checking and error tolerances for floating point approximation. The code is just an idea, not actually my function

Maybe u post your AxistoQuat??

temp_angle = acos(w);

scale = (float)sin(temp_angle);

if (0.0f == scale)) // axis does not matter
{
angle = 0.0f;
x = 0;
y = 0;
z = 1;
}
else // do as normal
{
angle = temp_angle * 2;

x = axis.x / scale;
y = axis.y / scale;
z = axis.z / scale;
}
Advertisement
maybe i''m misunderstanding axis-angle representation. i thought that meant a view vector pointing in direction of view and a roll angle. in that case the vector would make a difference. any ideas on how to convert to and from this format (view vector and roll angle)?
hmm...maybe that''s why this code didn''t work as expected.
however, this code is derived from the source that accompanies the gamasutra article in gdmag.

where D3DQUATERNION is just 4 floats (w,x,y,z)

void AxisAngleToQuat( const D3DVECTOR& axis, const float angle, D3DQUATERNION& quat )
{
float sq = sin( angle * 0.5f );
float cq = cos( angle * 0.5f );

quat.w = cq;
quat.x = axis.dvX * sq;
quat.y = axis.dvY * sq;
quat.z = axis.dvZ * sq;
}

crazy166


some people think i'm crazy, some people know it
Looks like the same idea

rad = (float)(DEGTORAD(angle) / 2.0f); // convert to rad

w = (float)cos(rad);

scale = (float)sin(rad);

x = q.x * scale;
y = q.y * scale;
z = q.z * scale;

// normalize the quaternion just to make sure

Note: I have taken out lots of error checks and error approximations.

Yes the vector would make a difference but if u are rotating around 0 or 360 degrees around an axis, why should the axis matter??
The problem you are having is because of your understanding of the axis-angle representation.

The representation in your code is made of a rotational axis and an angle to rotate around that axis. The axis is defined as the cross product between the up and view vectors. It is sometimes called the Right vector. A quaternion is the same thing but a bit tougher to visualize...

What you describe as a view vector and twist around that vector is a perfectly valid orientation representation. In fact it is used as a camera model a lot. It just isn''t what is meant by axis-angle representation in conjunction with quaternions.

-Jeff
thanx guys. i have found a way to go from "view vector-roll" to quaternion by remembering spherical coordinates from Calculus.
all i do is use my QuatToEulerAngles function and calc the vector coords as:

x = rho * sin( phi ) * cos( theta )
y = rho * sin( phi ) * sin( theta )
z = rho * cos( phi )

note that rho can be eliminated since that is the length of vector ( = 1 ) (pitch = phi, heading = theta)
and the opposite:

heading = tan-1( y/x )
pitch = cos-1( z )
EulerAnglesToQuat( heading, pitch, roll )

in both codes, roll = roll

of course, i haven''t tested this yet, but my conversions from Euler to quaternion seem to work ok.

thanx again,
crazy166

some people think i'm crazy, some people know it

This topic is closed to new replies.

Advertisement