cqrlib.h   cqrlib.h 
skipping to change at line 62 skipping to change at line 62
K. Shoemake, "Animating rotation with quaternion curves", K. Shoemake, "Animating rotation with quaternion curves",
ACM SIGGRAPH Computer Graphics, Vol 19, No. 3, pp 245--254, ACM SIGGRAPH Computer Graphics, Vol 19, No. 3, pp 245--254,
1985. 1985.
*/ */
#ifndef CQRLIB_H_INCLUDED #ifndef CQRLIB_H_INCLUDED
#define CQRLIB_H_INCLUDED #define CQRLIB_H_INCLUDED
#ifdef __cplusplus #ifdef __cplusplus
#include <climits>
#include <cmath>
template< typename DistanceType=double, typename VectorType=double[3], type
name MatrixType=double[9] >
class CPPQR
{
private:
DistanceType w, x, y, z;
public:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR( ) : // default constructor
w( DistanceType( 0.0 ) ),
x( DistanceType( 0.0 ) ),
y( DistanceType( 0.0 ) ),
z( DistanceType( 0.0 ) )
{
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR( const CPPQR& q ) // copy constructor
{
if ( this != &q )
{
w = q.w;
x = q.x;
y = q.y;
z = q.z;
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR( // constructor
const DistanceType& wi,
const DistanceType& xi,
const DistanceType& yi,
const DistanceType& zi
) :
w( wi ),
x( xi ),
y( yi ),
z( zi )
{
}
/* Set -- set the values of an existing quaternion = w +ix+jy+kz */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline void Set ( const DistanceType& wi,
const DistanceType& xi,
const DistanceType& yi,
const DistanceType& zi
)
{
w = wi;
x = xi;
y = yi;
z = zi;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline DistanceType GetW( void ) const
{
return( w );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline DistanceType GetX( void ) const
{
return( x );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline DistanceType GetY( void ) const
{
return( y );
}
inline DistanceType GetZ( void ) const
{
return( z );
}
/* Add -- add a quaternion (q1) to a quaternion (q2) */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR operator+ ( const CPPQR& q ) const
{
CPPQR temp;
temp.w = w + q.w;
temp.x = x + q.x;
temp.y = y + q.y;
temp.z = z + q.z;
return( temp );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR& operator+= ( const CPPQR& q )
{
w += q.w;
x += q.x;
y += q.y;
z += q.z;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR& operator-= ( const CPPQR& q )
{
w -= q.w;
x -= q.x;
y -= q.y;
z -= q.z;
}
/* Subtract -- subtract a quaternion (q2) from a quaternion (q1) */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR operator- ( const CPPQR& q ) const
{
CPPQR temp;
temp.w = w - q.w;
temp.x = x - q.x;
temp.y = y - q.y;
temp.z = z - q.z;
return( temp );
}
/* Multiply -- multiply a quaternion (q1) by quaternion (q2) */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR operator* ( const CPPQR& q ) const // multiply two quaternions
{
CPPQR temp;
temp.w = -z*q.z - y*q.y - x*q.x + w*q.w;
temp.x = y*q.z - z*q.y + w*q.x + x*q.w;
temp.y = -x*q.z + w*q.y + z*q.x + y*q.w;
temp.z = w*q.z + x*q.y - y*q.x + z*q.w;
return( temp );
}
/* Divide -- Divide a quaternion (q1) by quaternion (q2) */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR operator/ ( const CPPQR& q2 ) const
{
const DistanceType norm2sq = q2.w*q2.w + q2.x*q2.x + q2.y*q2.y + q2.z*q
2.z;
if ( norm2sq == 0.0 )
{
return( CPPQR( DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX ) );
}
CPPQR q;
q.w = z*q2.z + y*q2.y + x*q2.x + w*q2.w;
q.x = -y*q2.z + z*q2.y - w*q2.x + x*q2.w;
q.y = x*q2.z - w*q2.y - z*q2.x + y*q2.w;
q.z = -w*q2.z - x*q2.y + y*q2.x + z*q2.w;
return( q / norm2sq );
}
/* ScalarMultiply -- multiply a quaternion (q) by scalar (s) */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR operator* ( const DistanceType& d ) const // multiply by a con
stant
{
CPPQR temp;
temp.w = w*d;
temp.x = x*d;
temp.y = y*d;
temp.z = z*d;
return( temp );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR operator/ ( const DistanceType& d ) const // divide by a const
ant
{
CPPQR temp;
temp.w = w/d;
temp.x = x/d;
temp.y = y/d;
temp.z = z/d;
return( temp );
}
/* Conjugate -- Form the conjugate of a quaternion qconj */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR Conjugate ( void ) const
{
CPPQR conjugate;
conjugate.w = w;
conjugate.x = -x;
conjugate.y = -y;
conjugate.z = -z;
return( conjugate );
}
/* Normsq -- Form the normsquared of a quaternion */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline DistanceType Normsq ( void ) const
{
return( w*w + x*x + y*y + z*z );
}
/* Normsq -- Form the norm of a quaternion */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline DistanceType Norm ( void ) const
{
return sqrt( w*w + x*x + y*y + z*z );
}
/* Inverse -- Form the inverse of a quaternion */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR Inverse ( void ) const
{
CPPQR inversequaternion = (*this).Conjugate();
const DistanceType normsq = (*this).Normsq( );
if ( normsq > DistanceType( 0.0 ) )
{
inversequaternion = inversequaternion * DistanceType( 1.0 ) / norms
q;
}
else
{
inversequaternion = CPPQR( DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX );
}
return( inversequaternion );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR& operator= ( const CPPQR& q )
{
if ( this != &q )
{
w = q.w;
x = q.x;
y = q.y;
z = q.z;
}
return( *this );
}
/* Equal */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline bool operator== ( const CPPQR& q ) const
{
return( w==q.w && x==q.x && y==q.y && z==q.z );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline bool operator!= ( const CPPQR& q ) const
{
return( (w!=q.w) || (x!=q.x) || (y!=q.y) | (z!=q.z) );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline VectorType& operator* ( const VectorType& v )
{
return( RotateByQuaternion( v ) );
}
/* RotateByQuaternion -- Rotate a vector by a Quaternion, w = qvq* */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline void RotateByQuaternion(VectorType &w, const VectorType v )
{
CPPQR vquat( 0.0, v[0], v[1], v[2] );
const CPPQR wquat = (*this)*vquat;
const CPPQR qconj = *this.Conjugate( );
vquat = wquat * qconj;
w[0] = vquat.x; w[1] = vquat.y; w[2] = vquat.z;
return;
}
inline VectorType& RotateByQuaternion(const VectorType v )
{
CPPQR vquat( 0.0, v[0], v[1], v[2] );
const CPPQR wquat = (*this)*vquat;
const CPPQR qconj = *this.Conjugate( );
vquat = wquat * qconj;
return VectorType(vquat.x, vquat.y, vquat.z);
}
/* Axis2Quaternion -- Form the quaternion for a rotation around axis v by
angle theta */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
static inline CPPQR Axis2Quaternion ( const DistanceType& angle, const Vect
orType v )
{
return( Axis2Quaternion( v, angle ) );
}
/* Axis2Quaternion -- Form the quaternion for a rotation around axis v by
angle theta */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
static inline CPPQR Axis2Quaternion ( const VectorType v, const DistanceTyp
e& angle )
{
const DistanceType norm2sq = v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
if ( norm2sq == DistanceType(0.0) )
{
return( CPPQR( DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX ) );
}
const DistanceType sinOverNorm = sin(angle/2.0)/sqrt(norm2sq);
const CPPQR q( cos(angle/2.0), sinOverNorm*v[0], sinOverNorm*v[1], sinO
verNorm*v[2]);
return( q );
}
/* Matrix2Quaterion -- Form the quaternion from a 3x3 rotation matrix R */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
static inline void Matrix2Quaternion ( CPPQR& rotquaternion, const MatrixTy
pe m )
{
const DistanceType trace = m[0] + m[4] + m[8];
if ( trace > -0.75 )
{
rotquaternion.w = sqrt( (1.0+trace)) / 2.0;
const DistanceType recip = 0.25 / rotquaternion.w;
rotquaternion.z = (m[3]-m[1]) * recip;
rotquaternion.y = (m[2]-m[6]) * recip;
rotquaternion.x = (m[7]-m[5]) * recip;
return;
}
const DistanceType fourxsq = 1.0 + m[0] - m[4] - m[8];
if ( fourxsq >= 0.25 )
{
rotquaternion.x = sqrt( fourxsq ) / 2.0;
const DistanceType recip = 0.25 /rotquaternion.x;
rotquaternion.y = (m[3] + m[1])*recip;
rotquaternion.z = (m[2] + m[6])*recip;
rotquaternion.w = (m[7] - m[5])*recip;
return;
}
const DistanceType fourysq = 1.0 + m[4] - m[0] - m[8];
if ( fourysq >= 0.25 )
{
rotquaternion.y = sqrt( fourysq ) / 2.0;
const DistanceType recip = 0.25 / rotquaternion.y;
rotquaternion.x = (m[3] + m[1])*recip;
rotquaternion.w = (m[2] - m[6])*recip;
rotquaternion.z = (m[7] + m[5])*recip;
return;
}
const DistanceType fourzsq = 1. + m[8] - m[0] - m[4];
if ( fourzsq >= 0.25 )
{
rotquaternion.z = sqrt( fourzsq ) / 2.0;
const DistanceType recip = 0.25 / rotquaternion.z;
rotquaternion.w = (m[3] - m[1])*recip;
rotquaternion.x = (m[2] + m[6])*recip;
rotquaternion.y = (m[7] + m[5])*recip;
return;
}
rotquaternion.x = rotquaternion.y = rotquaternion.z = rotquaternion.
w = 0;
return;
}
static inline void Matrix2Quaternion (CPPQR& rotquaternion, const DistanceT
ype R[3][3] )
{
const DistanceType trace = R[0][0] + R[1][1] + R[2][2];
if ( trace > -0.75 )
{
rotquaternion.w = sqrt( (1.0+trace)) / 2.0;
const DistanceType recip = 0.25 / rotquaternion.w;
rotquaternion.z = (R[1][0]-R[0][1]) * recip;
rotquaternion.y = (R[0][2]-R[2][0]) * recip;
rotquaternion.x = (R[2][1]-R[1][2]) * recip;
return;
}
const DistanceType fourxsq = 1.0 + R[0][0] - R[1][1] - R[2][2];
if ( fourxsq >= 0.25 )
{
rotquaternion.x = sqrt( fourxsq ) / 2.0;
const DistanceType recip = 0.25 /rotquaternion.x;
rotquaternion.y = (R[1][0]+R[0][1])*recip;
rotquaternion.z = (R[0][2]+R[2][0])*recip;
rotquaternion.w = (R[2][1]-R[1][2])*recip;
return;
}
const DistanceType fourysq = 1.0 + R[1][1] - R[0][0] - R[2][2];
if ( fourysq >= 0.25 )
{
rotquaternion.y = sqrt( fourysq ) / 2.0;
const DistanceType recip = 0.25 / rotquaternion.y;
rotquaternion.x = (R[1][0]+R[0][1])*recip;
rotquaternion.w = (R[0][2]-R[2][0])*recip;
rotquaternion.z = (R[2][1]+R[1][2])*recip;
return;
}
const DistanceType fourzsq = 1. + R[2][2] - R[0][0] - R[1][1];
if ( fourzsq >= 0.25 )
{
rotquaternion.z = sqrt( fourzsq ) / 2.0;
const DistanceType recip = 0.25 / rotquaternion.z;
rotquaternion.w = (R[1][0]-R[0][1])*recip;
rotquaternion.x = (R[0][2]+R[2][0])*recip;
rotquaternion.y = (R[2][1]+R[1][2])*recip;
return;
}
rotquaternion.x = rotquaternion.y = rotquaternion.z = rotquaternion.
w = 0;
return;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
DistanceType operator[] ( const int k ) const
{
const int i = (k<0) ? 0 : ( (k>3)?3:k ) ;
if ( i==0 ) return w;
if ( i==1 ) return x;
if ( i==2 ) return y;
if ( i==3 ) return z;
return( 0 ); // just to keep compilers happy
}
/* Quaternion2Matrix -- Form the 3x3 rotation matrix from a quaternion */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
static inline void Quaternion2Matrix(MatrixType& m, const CPPQR q )
{
const DistanceType ww = q.w*q.w;
const DistanceType xx = q.x*q.x;
const DistanceType yy = q.y*q.y;
const DistanceType zz = q.z*q.z;
const DistanceType twoxy = 2.0 * q.x*q.y;
const DistanceType twoyz = 2.0 * q.y*q.z;
const DistanceType twoxz = 2.0 * q.x*q.z;
const DistanceType twowx = 2.0 * q.w*q.x;
const DistanceType twowy = 2.0 * q.w*q.y;
const DistanceType twowz = 2.0 * q.w*q.z;
m[0] = ww+xx-yy-zz; m[1] = twoxy - twowz; m[2] = twoxz + twowy;
m[3] = twoxy + twowz; m[4] = ww-xx+yy-zz; m[5] = twoyz - twowx;
m[6] = twoxz - twowy; m[7] = twoyz + twowx; m[8] = ww-xx-yy+zz;
return;
}
static inline void Quaternion2Matrix( DistanceType m[3][3], const CPPQR q )
{
const DistanceType ww = q.w*q.w;
const DistanceType xx = q.x*q.x;
const DistanceType yy = q.y*q.y;
const DistanceType zz = q.z*q.z;
const DistanceType twoxy = 2.0 * q.x*q.y;
const DistanceType twoyz = 2.0 * q.y*q.z;
const DistanceType twoxz = 2.0 * q.x*q.z;
const DistanceType twowx = 2.0 * q.w*q.x;
const DistanceType twowy = 2.0 * q.w*q.y;
const DistanceType twowz = 2.0 * q.w*q.z;
m[0][0] = ww+xx-yy-zz; m[0][1] = twoxy - twowz; m[0][2] = twoxz + two
wy;
m[1][0] = twoxy + twowz; m[1][1] = ww-xx+yy-zz; m[0][2] = twoyz - two
wx;
m[2][0] = twoxz - twowy; m[2][1] = twoyz + twowx; m[2][2] = ww-xx-yy+zz
;
return;
}
// end Quaternion2Matrix
/* Get a unit quaternion from a general one */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline CPPQR UnitQ( void ) const
{
const DistanceType normsq = Normsq( );
if ( normsq == 0.0 )
{
return( CPPQR( DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX ) );
}
else
{
return( (*this) / sqrt( Normsq( ) ) );
}
} // end UnitQ
/* Quaternion2Angles -- Convert a Quaternion into Euler Angles for Rz(Ry(Rx
))) convention */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
inline bool Quaternion2Angles ( DistanceType& rotX, DistanceType& rotY, Dis
tanceType& rotZ ) const
{
const DistanceType PI = 4.0 * atan( 1.0 );
const DistanceType rmx0 = w*w + x*x - y*y - z*z;
const DistanceType rmx1 = 2.0 * ( x*y - w*z );
const DistanceType rmy0 = 2.0 * ( x*y + w*z );
const DistanceType rmy1 = w*w - x*x + y*y - z*z;
const DistanceType rmz0 = 2.0 * (x*z - w*y );
const DistanceType rmz1 = 2.0 * (w*x + y*z );
const DistanceType rmz2 = w*w - x*x - y*y + z*z;
DistanceType srx, sry, srz, trX, trY, trZ;
if ( rmz0 >= 1.0 )
{
sry = -0.5 * PI;
}
else if ( rmz0 <= -1.0 )
{
sry = 0.5 * PI;
}
else
{
sry = asin( -rmz0 );
}
if ( rmz0 > 0.9999995 )
{
srx = atan2( -rmx1, rmy1 );
srz = 0.0;
}
else if ( rmz0 < -0.9999995 )
{
srx = atan2( rmx1, rmy1 );
srz = 0.0;
}
else
{
srx = atan2( rmz1, rmz2 );
srz = atan2( rmy0, rmx0 );
}
trX = PI + srx;
if ( trX > 2.0 * PI ) trX -= 2.0 * PI;
trY = PI + sry;
if ( trY > 2.0 * PI ) trY -= 2.0 * PI;
trZ = PI + srz;
if ( trZ > 2.0 * PI ) trZ -= 2.0 * PI;
const DistanceType nsum = fabs( cos(srx)-cos(rotX)) + fabs( sin(srx
)-sin(rotX))
+ fabs( cos(sry)-cos(rotY)) + fabs( sin(sry)-sin(rotY))
+ fabs( cos(srz)-cos(rotZ)) + fabs( sin(srz)-sin(rotZ));
const DistanceType tsum = fabs( cos(trX)-cos(rotX)) + fabs( sin(trX
)-sin(rotX))
+ fabs( cos(trY)-cos(rotY)) + fabs( sin(trY)-sin(rotY))
+ fabs( cos(trZ)-cos(rotZ)) + fabs( sin(trZ)-sin(rotZ));
if ( nsum < tsum )
{
rotX = srx; rotY = sry; rotZ = srz;
}
else
{
rotX = trX; rotY = trY; rotZ = trZ;
}
return( true );
} // end Quaternion2Angles
/* Angles2Quaternion -- Convert Euler Angles for Rz(Ry(Rx))) convention int
o a quaternion */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++*/
static inline CPPQR Angles2Quaternion ( const DistanceType& rotX, const Dis
tanceType& rotY, const DistanceType& rotZ )
{
const DistanceType cx = cos( rotX / 2.0 );
const DistanceType sx = sin( rotX / 2.0 );
const DistanceType cy = cos( rotY / 2.0 );
const DistanceType sy = sin( rotY / 2.0 );
const DistanceType cz = cos( rotZ / 2.0 );
const DistanceType sz = sin( rotZ / 2.0 );
const CPPQR q( cx*cy*cz + sx*sy*sz,
sx*cy*cz - cx*sy*sz,
cx*sy*cz + sx*cy*sz,
cx*cy*sz - sx*sy*cz
);
return( q );
} // end Angles2Quaternion
static inline CPPQR Point2Quaternion( const DistanceType v[3] )
{
return( CPPQR( 0.0, v[0], v[1], v[2] ) );
}
}; // end class CPPQR
#ifndef CQR_NOCCODE
extern "C" { extern "C" {
#endif
#endif
#ifndef __cplusplus
#ifndef CQR_NOCCODE
#include <math.h>
#endif
#endif #endif
#ifndef CQR_NOCCODE
#ifdef CQR_USE_FAR #ifdef CQR_USE_FAR
#include <malloc.h> #include <malloc.h>
#define CQR_FAR __far #define CQR_FAR __far
#define CQR_MALLOC _fmalloc #define CQR_MALLOC _fmalloc
#define CQR_FREE _ffree #define CQR_FREE _ffree
#define CQR_MEMSET _fmemset #define CQR_MEMSET _fmemset
#define CQR_MEMMOVE _fmemmove #define CQR_MEMMOVE _fmemmove
#else #else
#include <stdlib.h> #include <stdlib.h>
#define CQR_FAR #define CQR_FAR
#define CQR_MALLOC malloc #define CQR_MALLOC malloc
#define CQR_FREE free #define CQR_FREE free
#define CQR_MEMSET memset #define CQR_MEMSET memset
#define CQR_MEMMOVE memmove #define CQR_MEMMOVE memmove
#endif #endif
#include <math.h>
#define CQR_FAILED 4 #define CQR_FAILED 4
#define CQR_NO_MEMORY 2 #define CQR_NO_MEMORY 2
#define CQR_BAD_ARGUMENT 1 #define CQR_BAD_ARGUMENT 1
#define CQR_SUCCESS 0 #define CQR_SUCCESS 0
typedef struct { typedef struct {
double w; double w;
double x; double x;
double y; double y;
double z; } CQRQuaternion; double z; } CQRQuaternion;
typedef CQRQuaternion * CQRQuaternionHandle; typedef CQRQuaternion CQR_FAR * CQRQuaternionHandle;
/* CQR Macros */ /* CQR Macros */
#define CQRMCopy(copy,orig) \ #define CQRMCopy(copy,orig) \
(copy).w = (orig).w; (copy).x = (orig).x; (copy).y = (orig).y; (copy).z = ( orig).z; (copy).w = (orig).w; (copy).x = (orig).x; (copy).y = (orig).y; (copy).z = ( orig).z;
#define CQRMSet(q,qw,qx,qy,qz) \ #define CQRMSet(q,qw,qx,qy,qz) \
(q).w = (qw); (q).x = (qx); (q).y = (qy); (q).z = (qz); (q).w = (qw); (q).x = (qx); (q).y = (qy); (q).z = (qz);
#define CQRMAdd(sum,q1,q2) \ #define CQRMAdd(sum,q1,q2) \
skipping to change at line 188 skipping to change at line 777
int CQREqual (CQRQuaternionHandle q1, CQRQuaternionHandle q2 ); int CQREqual (CQRQuaternionHandle q1, CQRQuaternionHandle q2 );
/* CQRConjugate -- Form the conjugate of a quaternion qconj */ /* CQRConjugate -- Form the conjugate of a quaternion qconj */
int CQRConjugate (CQRQuaternionHandle qconjgate, CQRQuaternionHandle qu aternion); int CQRConjugate (CQRQuaternionHandle qconjgate, CQRQuaternionHandle qu aternion);
/* CQRNormsq -- Form the normsquared of a quaternion */ /* CQRNormsq -- Form the normsquared of a quaternion */
int CQRNormsq (double * normsq, CQRQuaternionHandle quaternion ) ; int CQRNormsq (double * normsq, CQRQuaternionHandle quaternion ) ;
/* CQRNorm -- Form the norm of a quaternion */
int CQRNormsq (double * norm, CQRQuaternionHandle quaternion ) ;
/* CQRInverse -- Form the inverse of a quaternion */ /* CQRInverse -- Form the inverse of a quaternion */
int CQRInverse (CQRQuaternionHandle inversequaternion, CQRQuaternionHan dle quaternion ); int CQRInverse (CQRQuaternionHandle inversequaternion, CQRQuaternionHan dle quaternion );
/* CQRRotateByQuaternion -- Rotate a vector by a Quaternion, w = qvq* * / /* CQRRotateByQuaternion -- Rotate a vector by a Quaternion, w = qvq* * /
int CQRRotateByQuaternion(double CQR_FAR * w, CQRQuaternionHandle rotqu aternion, double CQR_FAR * v); int CQRRotateByQuaternion(double CQR_FAR * w, CQRQuaternionHandle rotqu aternion, double CQR_FAR * v);
/* CQRAxis2Quaternion -- Form the quaternion for a rotation around axis v by angle theta */ /* CQRAxis2Quaternion -- Form the quaternion for a rotation around axis v by angle theta */
skipping to change at line 221 skipping to change at line 814
/* CQRAngles2Quaternion -- Convert Euler Angles for Rz(Ry(Rx))) convent ion into a quaternion */ /* CQRAngles2Quaternion -- Convert Euler Angles for Rz(Ry(Rx))) convent ion into a quaternion */
int CQRAngles2Quaternion (CQRQuaternionHandle rotquaternion, double Rot X, double RotY, double RotZ ); int CQRAngles2Quaternion (CQRQuaternionHandle rotquaternion, double Rot X, double RotY, double RotZ );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif
#endif #endif
 End of changes. 9 change blocks. 
2 lines changed or deleted 651 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/