一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类);四元数(quaternion)模板类的使用

来源:互联网 发布:希克森cba数据 编辑:程序博客网 时间:2024/05/16 12:29

一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类)
部分DX矩阵函数的实现
namespace Han
{
 FLOAT WINAPI D3DXMatrixDeterminant(CONST D3DXMATRIX *pM)
{
     D3DXMATRIX mtx=*pM;
     FLOAT ret=Bsdet(&mtx(0,0),4);//第一个参数是输入输出参数
     return ret;
}
D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX *pOut)
{
//identity matrix
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=1;
pOut->m[1][1]=1;
pOut->m[2][2]=1;
pOut->m[3][3]=1;
return pOut;
}
//Build a matrix which scales by (sx,sy,sz)
D3DXMATRIX* D3DXMatrixScaling(D3DXMATRIX *pOut,FLOAT sx,FLOAT sy,FLOAT sz)
{
//创建一个沿着X,Y和Z轴方向缩放矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=sx;
pOut->m[1][1]=sy;
pOut->m[2][2]=sz;
pOut->m[3][3]=1;
return pOut;
}
//Build a matrix which translates by (x,y,z)
D3DXMATRIX* D3DXMatrixTranslation(D3DXMATRIX *pOut,FLOAT x,FLOAT y,FLOAT z)
{
//创建一个沿着X,Y和Z轴方向平移矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=1;
pOut->m[1][1]=1;
pOut->m[2][2]=1;
pOut->m[3][3]=1;
pOut->m[3][0]=x;
pOut->m[3][1]=y;
pOut->m[3][2]=z;
return pOut;
}
//Build a matrix which rotates around the X axis
D3DXMATRIX* D3DXMatrixRotationX(D3DXMATRIX *pOut,FLOAT Angle)
{
//创建一个绕X轴旋转Angle弧度的旋转矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=1;
pOut->m[1][1]=cos(Angle);
pOut->m[2][2]=cos(Angle);
pOut->m[3][3]=1;
pOut->m[1][2]=sin(Angle);
pOut->m[2][1]=-sin(Angle);
return pOut;
}
//Build a matrix which rotates around the Y axis
D3DXMATRIX* D3DXMatrixRotationY(D3DXMATRIX *pOut,FLOAT Angle)
{
//创建一个绕Y轴旋转Angle弧度的旋转矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=cos(Angle);
pOut->m[1][1]=1;
pOut->m[2][2]=cos(Angle);
pOut->m[3][3]=1;
pOut->m[0][2]=-sin(Angle);
pOut->m[2][0]=sin(Angle);
return pOut;
}
//Build a matrix which rotates around the Z axis
D3DXMATRIX* D3DXMatrixRotationZ(D3DXMATRIX *pOut,FLOAT Angle)
{
//创建一个绕Z轴旋转Angle弧度的旋转矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=cos(Angle);
pOut->m[1][1]=cos(Angle);
pOut->m[2][2]=1;
pOut->m[3][3]=1;
pOut->m[0][1]=sin(Angle);
pOut->m[1][0]=-sin(Angle);
return pOut;
}
//Transform (x,y,z,1) by matrix
D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4 *pOut,CONST D3DXVECTOR4 *pV,CONST D3DXMATRIX *pM)
{
#if 1
//MV
D3DXVECTOR4 v(pV->x,pV->y,pV->z,1);
pOut->x=(*pM)(0,0)*v.x+(*pM)(0,1)*v.y+(*pM)(0,2)*v.z+(*pM)(0,3)*v.w;
pOut->y=(*pM)(1,0)*v.x+(*pM)(1,1)*v.y+(*pM)(1,2)*v.z+(*pM)(1,3)*v.w;
pOut->z=(*pM)(2,0)*v.x+(*pM)(2,1)*v.y+(*pM)(2,2)*v.z+(*pM)(2,3)*v.w;
pOut->w=(*pM)(3,0)*v.x+(*pM)(3,1)*v.y+(*pM)(3,2)*v.z+(*pM)(3,3)*v.w;
return pOut;
#else
//VM
D3DXVECTOR4 v(pV->x,pV->y,pV->z,1);
pOut->x=(*pM)(0,0)*v.x+(*pM)(1,0)*v.y+(*pM)(2,0)*v.z+(*pM)(3,0)*v.w;
pOut->y=(*pM)(0,1)*v.x+(*pM)(1,1)*v.y+(*pM)(2,1)*v.z+(*pM)(3,1)*v.w;
pOut->z=(*pM)(0,2)*v.x+(*pM)(1,2)*v.y+(*pM)(2,2)*v.z+(*pM)(3,2)*v.w;
pOut->w=(*pM)(0,3)*v.x+(*pM)(1,3)*v.y+(*pM)(2,3)*v.z+(*pM)(3,3)*v.w;
return pOut;
#endif
return NULL;
}
};
----实矩阵乘法----
-3,1,-1,
-7,5,-1,
-6,6,-2,
-3,1,-1,
-7,5,-1,
-6,6,-2,
8,-4,4,
-8,12,4,
-12,12,4,
----实矩阵求逆----
-0.25,-0.25,0.25,
-0.5,3.47694e-008,0.25,
-0.75,0.75,-0.5,
-3,1,-1,
-7,5,-1,
-6,6,-2,
----实矩阵求行列式的值----
16
16
// 矩阵标准API(实矩阵相乘,Bsdet求实方阵的行列式值,求实方阵的逆)的C++封装,一个可复用的C++ 3阶方阵类
//
#include"stdafx.h"
#include<cmath>
#include<iostream>
using namespace std;
template<class T>
void __stdcall Brmul(T *a,T *b,int m,int n,int k,T *c)
{
 int i,j,l,u;
 for (i=0; i<=m-1; i++)
  for (j=0; j<=k-1; j++)
  {
   u=i*k+j;
   c[u]=0.0;
   for(l=0; l<=n-1; l++)
    c[u]=c[u]+a[i*n+l]*b[l*k+j];
  }
  return;
}
template<class T>
//第一个参数是输入输出参数
T __stdcall Bsdet(T *a,int n)
{
 int i,j,k,is,js,l,u,v;
 T f,det,q,d;
 f=1.0; det=1.0;
 for (k=0; k<=n-2; k++)
 {
  q=0.0;
  for (i=k; i<=n-1; i++)
   for (j=k; j<=n-1; j++)
   {
    l=i*n+j;
    d=fabs(a[l]);
    if (d>q)
    {
     q=d;
     is=i;
     js=j;
    }
   }
   if(q+1.0==1.0)
   {
    det=0.0;
    return(det);
   }
   if(is!=k)
   {
    f=-f;
    for (j=k; j<=n-1; j++)
    {
     u=k*n+j;
     v=is*n+j;
     d=a[u];
     a[u]=a[v];
     a[v]=d;
    }
   }
   if(js!=k)
   {
    f=-f;
    for (i=k; i<=n-1; i++)
    {
     u=i*n+js;
     v=i*n+k;
     d=a[u];
     a[u]=a[v];
     a[v]=d;
    }
   }
   l=k*n+k;
   det=det*a[l];
   for (i=k+1; i<=n-1; i++)
   {
    d=a[i*n+k]/a[l];
    for (j=k+1; j<=n-1; j++)
    {
     u=i*n+j;
     a[u]=a[u]-d*a[k*n+j];
    }
   }
 }
 det=f*det*a[n*n-1];
 return(det);
}
template<class T>
int __stdcall Brinv(T *a,int n)
{
 int *is,*js,i,j,k,l,u,v;
 T d,p;
 is=(int*)malloc(n*sizeof(int));
 js=(int*)malloc(n*sizeof(int));
 for (k=0; k<=n-1; k++)
 {
  d=0.0;
  for (i=k; i<=n-1; i++)
   for (j=k; j<=n-1; j++)
   {
    l=i*n+j;
    p=fabs(a[l]);
    if (p>d)
    {
     d=p;
     is[k]=i;
     js[k]=j;
    }
   }
   if (d+1.0==1.0)
   {
    free(is);
    free(js);
    printf("err**not inv\n");
    return(0);
   }
   if (is[k]!=k)
    for (j=0; j<=n-1; j++)
    {
     u=k*n+j;
     v=is[k]*n+j;
     p=a[u];
     a[u]=a[v];
     a[v]=p;
    }
    if (js[k]!=k)
     for (i=0; i<=n-1; i++)
     {
      u=i*n+k;
      v=i*n+js[k];
      p=a[u];
      a[u]=a[v];
      a[v]=p;
     }
     l=k*n+k;
     a[l]=1.0/a[l];
     for (j=0; j<=n-1; j++)
      if (j!=k)
      {
       u=k*n+j;
       a[u]=a[u]*a[l];
      }
      for (i=0; i<=n-1; i++)
       if (i!=k)
        for (j=0; j<=n-1; j++)
         if (j!=k)
         {
          u=i*n+j;
          a[u]=a[u]-a[i*n+k]*a[k*n+j];
         }
         for (i=0; i<=n-1; i++)
          if (i!=k)
          {
           u=i*n+k;
           a[u]=-a[u]*a[l];
          }
 }
 for(k=n-1; k>=0; k--)
 {
  if (js[k]!=k)
   for (j=0; j<=n-1; j++)
   {
    u=k*n+j;
    v=js[k]*n+j;
    p=a[u];
    a[u]=a[v];
    a[v]=p;
   }
   if (is[k]!=k)
    for (i=0; i<=n-1; i++)
    {
     u=i*n+k;
     v=i*n+is[k];
     p=a[u];
     a[u]=a[v];
     a[v]=p;
    }
 }
 free(is);
 free(js);
 return(1);
}
 
// From gamasutra. This file may follow different licence features.
// A floating point number
//
typedef float SCALAR;
//
// A 3D vector
//
class VECTOR
{
public:
 SCALAR x,y,z; //x,y,z coordinates
public:
 VECTOR() : x(0), y(0), z(0) {}
 VECTOR( const SCALAR& a, const SCALAR& b, const SCALAR& c ) : x(a), y(b), z(c) {}
 //index a component
 //NOTE: returning a reference allows
 //you to assign the indexed element
 SCALAR& operator [] ( const long i )
 {
  return *((&x) + i);
 }
//compare
 const bool operator == ( const VECTOR& v ) const
 {
  return (v.x==x && v.y==y && v.z==z);
 }
 const bool operator != ( const VECTOR& v ) const
 {
  return !(v == *this);
 }
//negate
 const VECTOR operator - () const
 {
  return VECTOR( -x, -y, -z );
 }
//assign
 const VECTOR& operator = ( const VECTOR& v )
 {
  x = v.x;
  y = v.y;
  z = v.z;
  return *this;
 }
//increment
 const VECTOR& operator += ( const VECTOR& v )
 {
  x+=v.x;
  y+=v.y;
  z+=v.z;
  return *this;
 }
//decrement
 const VECTOR& operator -= ( const VECTOR& v )
 {
  x-=v.x;
  y-=v.y;
  z-=v.z;
  return *this;
 }
//self-multiply
 const VECTOR& operator *= ( const SCALAR& s )
 {
  x*=s;
  y*=s;
  z*=s;
  return *this;
 }
//self-divide
 const VECTOR& operator /= ( const SCALAR& s )
 {
  const SCALAR r = 1 / s;
  x *= r;
  y *= r;
  z *= r;
  return *this;
 }
//add
 const VECTOR operator + ( const VECTOR& v ) const
 {
  return VECTOR(x + v.x, y + v.y, z + v.z);
 }
//subtract
 const VECTOR operator - ( const VECTOR& v ) const
 {
  return VECTOR(x - v.x, y - v.y, z - v.z);
 }
//post-multiply by a scalar
 const VECTOR operator * ( const SCALAR& s ) const
 {
  return VECTOR( x*s, y*s, z*s );
 }
//pre-multiply by a scalar
 friend inline const VECTOR operator * ( const SCALAR& s, const VECTOR& v )
 {
  return v * s;
 }
//divide
 const VECTOR operator / (SCALAR s) const
 {
  s = 1/s;
  return VECTOR( s*x, s*y, s*z );
 }
//cross product
 const VECTOR cross( const VECTOR& v ) const
 {
  //Davis, Snider, "Introduction to Vector Analysis", p. 44
  return VECTOR( y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x );
 }
//scalar dot product
 const SCALAR dot( const VECTOR& v ) const
 {
  return x*v.x + y*v.y + z*v.z;
 }
//length
 const SCALAR length() const
 {
  return (SCALAR)sqrt( (double)this->dot(*this) );
 }
//unit vector
 const VECTOR unit() const
 {
 return (*this) / length();
 }
//make this a unit vector
 void normalize()
 {
  (*this) /= length();
 }
//equal within an error 慹?
 const bool nearlyEquals( const VECTOR& v, const SCALAR e ) const
 {
  return fabs(x-v.x)<e && fabs(y-v.y)<e && fabs(z-v.z)<e;
 }
};
//
// A 3D position
//
//typedef VECTOR POINT;
// From gamasutra. This file may follow different licence features.
// A 3x3 matrix
//
class MATRIX
{
public:
 VECTOR C[3]; //column vectors,应该是行向量或列向量,对象占用4*9=36字节的内存空间,内存顺序与真数组的内存顺序是一致的
public:
 MATRIX()
 {
  //identity matrix
  C[0].x = 1;
  C[1].y = 1;
  C[2].z = 1;
 }
 MATRIX( const VECTOR& c0, const VECTOR& c1, const VECTOR& c2 )
 {
  C[0] = c0;
  C[1] = c1;
  C[2] = c2;
 }
 //index a column, allow assignment
 //NOTE: using this index operator along with the vector index
 //gives you M[column][row], not the standard M[row][column]
 VECTOR& operator [] ( long i )
 {
  return C[i];
 }
 //compare
 const bool operator == ( const MATRIX& m ) const
 {
  return C[0]==m.C[0] && C[1]==m.C[1] && C[2]==m.C[2];
 }
 const bool operator != ( const MATRIX& m ) const
 {
  return !(m == *this);
 }
 //assign
 const MATRIX& operator = ( const MATRIX& m )
 {
  C[0] = m.C[0];
  C[1] = m.C[1];
  C[2] = m.C[2];
  return *this;
 }
 //increment
 const MATRIX& operator +=( const MATRIX& m )
 {
  C[0] += m.C[0];
  C[1] += m.C[1];
  C[2] += m.C[2];
  return *this;
 }
 //decrement
 const MATRIX& operator -=( const MATRIX& m )
 {
  C[0] -= m.C[0];
  C[1] -= m.C[1];
  C[2] -= m.C[2];
  return *this;
 }
 //self-multiply by a scalar
 const MATRIX& operator *= ( const SCALAR& s )
 {
  C[0] *= s;
  C[1] *= s;
  C[2] *= s;
  return *this;
 }
 //self-multiply by a matrix
 const MATRIX& operator *= ( const MATRIX& m )
 {
  //NOTE: don抰 change the columns
  //in the middle of the operation
  MATRIX temp = (*this);
  C[0] = temp * m.C[0];
  C[1] = temp * m.C[1];
  C[2] = temp * m.C[2];
  return *this;
 }
 //add
 const MATRIX operator + ( const MATRIX& m ) const
 {
  return MATRIX( C[0] + m.C[0], C[1] + m.C[1], C[2] + m.C[2] );
 }
 //subtract
 const MATRIX operator - ( const MATRIX& m ) const
 {
  return MATRIX( C[0] - m.C[0], C[1] - m.C[1], C[2] - m.C[2] );
 }
 //post-multiply by a scalar
 const MATRIX operator * ( const SCALAR& s ) const
 {
  return MATRIX( C[0]*s, C[1]*s, C[2]*s );
 }
 //pre-multiply by a scalar
 friend inline const MATRIX operator * ( const SCALAR& s, const MATRIX& m )
 {
  return m * s;
 }
 //post-multiply by a vector
 const VECTOR operator * ( const VECTOR& v ) const
 {
  return( C[0]*v.x + C[1]*v.y + C[2]*v.z );
 }
 //pre-multiply by a vector
 inline friend const VECTOR operator * ( const VECTOR& v, const MATRIX& m )
 {
  return VECTOR( m.C[0].dot(v), m.C[1].dot(v), m.C[2].dot(v) );
 }
 //post-multiply by a matrix
 const MATRIX operator * ( const MATRIX& m ) const
 {
  return MATRIX( (*this) * m.C[0], (*this) * m.C[1], (*this) * m.C[2] );
 }
 //transpose
 MATRIX transpose() const
 {
  //turn columns on their side
  return MATRIX( VECTOR( C[0].x, C[1].x, C[2].x ), //column 0
   VECTOR( C[0].y, C[1].y, C[2].y ), //column 1
   VECTOR( C[0].z, C[1].z, C[2].z ) //column 2
   );
 }
 //scalar determinant
 const SCALAR determinant() const
 {
  //Lang, "Linear Algebra", p. 143
  return C[0].dot( C[1].cross(C[2]) );
 }
 //add by Ivan_han
 const SCALAR det() const
 {
  MATRIX mtx=*this;
  SCALAR ret=Bsdet(&mtx[0][0],3);//第一个参数是输入输出参数
  return ret;
 }
 //matrix inverse,去掉返回值类型中的const
 MATRIX inverse() const
 {
    MATRIX mtx=*this;
    int i=Brinv((SCALAR *)&mtx[0][0],3);
    if(i!=0)
     return mtx;
    return MATRIX();
 }
 //add by Ivan_han
 friend ostream& operator<< (ostream& os,MATRIX& mtx);
};
//add by Ivan_han
ostream& operator<< (ostream& os,MATRIX& mtx)
{
 for(int i=0;i<=2;i++)
 {
  for(int j=0;j<=2;j++)
   os<<mtx[i][j]<<",";
  os<<endl;
 }
 return os;
}
int main(void)
{
   int i,j;
   static float A[3][3]=
   {
    {-3,1,-1},
    {-7,5,-1},
    {-6,6,-2},
   };
   static float C[3][3],B[3][3]=
   {
    {-3,1,-1},
    {-7,5,-1},
    {-6,6,-2},
   };
   cout<<"----实矩阵乘法----"<<endl;
   Brmul(&A[0][0],&B[0][0],3,3,3,&C[0][0]);
   MATRIX mtxA,mtxB,mtxC;
   memcpy(&mtxA,A,sizeof(A));
   memcpy(&mtxB,B,sizeof(B));
   memcpy(&mtxC,C,sizeof(C));
   cout<<mtxA<<endl;
   cout<<mtxB<<endl;
   cout<<mtxC<<endl;
   MATRIX mtxD=mtxA.inverse();
   cout<<"----实矩阵求逆----"<<endl;
   cout<<mtxD<<endl;
   cout<<mtxD.inverse()<<endl;
   cout<<"----实矩阵求行列式的值----"<<endl;
   cout<<mtxA.determinant()<<endl;
   cout<<mtxA.det()<<endl;
   system("pause");
   return 0;
}
----实矩阵乘法----
1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16,
1,1,3,4,
1,2,3,2,
2,4,1,3,
5,7,1,4,
29,45,16,33,
65,101,48,85,
101,157,80,137,
137,213,112,189,
err**not inv
----实矩阵求逆----
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1,
1,0,0,-0,
-0,1,0,-0,
0,-0,1,-0,
0,0,-0,1,
----实矩阵求行列式的值----
-0
// 矩阵标准API(实矩阵相乘,Bsdet求实方阵的行列式值,求实方阵的逆)的C++封装,一个可复用的C++ 4阶方阵类
//
#include"stdafx.h"
#include<cmath>
#include<iostream>
using namespace std;
template<class T>
void __stdcall Brmul(T *a,T *b,int m,int n,int k,T *c)
{
 int i,j,l,u;
 for (i=0; i<=m-1; i++)
  for (j=0; j<=k-1; j++)
  {
   u=i*k+j;
   c[u]=0.0;
   for(l=0; l<=n-1; l++)
    c[u]=c[u]+a[i*n+l]*b[l*k+j];
  }
  return;
}
template<class T>
//第一个参数是输入输出参数
T __stdcall Bsdet(T *a,int n)
{
 int i,j,k,is,js,l,u,v;
 T f,det,q,d;
 f=1.0; det=1.0;
 for (k=0; k<=n-2; k++)
 {
  q=0.0;
  for (i=k; i<=n-1; i++)
   for (j=k; j<=n-1; j++)
   {
    l=i*n+j;
    d=fabs(a[l]);
    if (d>q)
    {
     q=d;
     is=i;
     js=j;
    }
   }
   if(q+1.0==1.0)
   {
    det=0.0;
    return(det);
   }
   if(is!=k)
   {
    f=-f;
    for (j=k; j<=n-1; j++)
    {
     u=k*n+j;
     v=is*n+j;
     d=a[u];
     a[u]=a[v];
     a[v]=d;
    }
   }
   if(js!=k)
   {
    f=-f;
    for (i=k; i<=n-1; i++)
    {
     u=i*n+js;
     v=i*n+k;
     d=a[u];
     a[u]=a[v];
     a[v]=d;
    }
   }
   l=k*n+k;
   det=det*a[l];
   for (i=k+1; i<=n-1; i++)
   {
    d=a[i*n+k]/a[l];
    for (j=k+1; j<=n-1; j++)
    {
     u=i*n+j;
     a[u]=a[u]-d*a[k*n+j];
    }
   }
 }
 det=f*det*a[n*n-1];
 return(det);
}
template<class T>
int __stdcall Brinv(T *a,int n)
{
 int *is,*js,i,j,k,l,u,v;
 T d,p;
 is=(int*)malloc(n*sizeof(int));
 js=(int*)malloc(n*sizeof(int));
 for (k=0; k<=n-1; k++)
 {
  d=0.0;
  for (i=k; i<=n-1; i++)
   for (j=k; j<=n-1; j++)
   {
    l=i*n+j;
    p=fabs(a[l]);
    if (p>d)
    {
     d=p;
     is[k]=i;
     js[k]=j;
    }
   }
   if (d+1.0==1.0)
   {
    free(is);
    free(js);
    printf("err**not inv\n");
    return(0);
   }
   if (is[k]!=k)
    for (j=0; j<=n-1; j++)
    {
     u=k*n+j;
     v=is[k]*n+j;
     p=a[u];
     a[u]=a[v];
     a[v]=p;
    }
    if (js[k]!=k)
     for (i=0; i<=n-1; i++)
     {
      u=i*n+k;
      v=i*n+js[k];
      p=a[u];
      a[u]=a[v];
      a[v]=p;
     }
     l=k*n+k;
     a[l]=1.0/a[l];
     for (j=0; j<=n-1; j++)
      if (j!=k)
      {
       u=k*n+j;
       a[u]=a[u]*a[l];
      }
      for (i=0; i<=n-1; i++)
       if (i!=k)
        for (j=0; j<=n-1; j++)
         if (j!=k)
         {
          u=i*n+j;
          a[u]=a[u]-a[i*n+k]*a[k*n+j];
         }
         for (i=0; i<=n-1; i++)
          if (i!=k)
          {
           u=i*n+k;
           a[u]=-a[u]*a[l];
          }
 }
 for(k=n-1; k>=0; k--)
 {
  if (js[k]!=k)
   for (j=0; j<=n-1; j++)
   {
    u=k*n+j;
    v=js[k]*n+j;
    p=a[u];
    a[u]=a[v];
    a[v]=p;
   }
   if (is[k]!=k)
    for (i=0; i<=n-1; i++)
    {
     u=i*n+k;
     v=i*n+is[k];
     p=a[u];
     a[u]=a[v];
     a[v]=p;
    }
 }
 free(is);
 free(js);
 return(1);
}
 
// From gamasutra. This file may follow different licence features.
// A floating point number
//
typedef float SCALAR;
//
// A 4D vector
//
class VECTOR4
{
public:
 SCALAR x,y,z,w; //x,y,z,w coordinates
public:
 VECTOR4() : x(0), y(0), z(0),w(0) {}
 VECTOR4( const SCALAR& a, const SCALAR& b, const SCALAR& c , const SCALAR& d) : x(a), y(b), z(c), w(d) {}
 //index a component
 //NOTE: returning a reference allows
 //you to assign the indexed element
 SCALAR& operator [] ( const long i )
 {
  return *((&x) + i);
 }
//compare
 const bool operator == ( const VECTOR4& v ) const
 {
  return (v.x==x && v.y==y && v.z==z && v.w==w);
 }
 const bool operator != ( const VECTOR4& v ) const
 {
  return !(v == *this);
 }
//negate
 const VECTOR4 operator - () const
 {
  return VECTOR4( -x, -y, -z ,-w);
 }
//assign
 const VECTOR4& operator = ( const VECTOR4& v )
 {
  x = v.x;
  y = v.y;
  z = v.z;
  w = v.w;
  return *this;
 }
//increment
 const VECTOR4& operator += ( const VECTOR4& v )
 {
  x+=v.x;
  y+=v.y;
  z+=v.z;
  w+=v.w;
  return *this;
 }
//decrement
 const VECTOR4& operator -= ( const VECTOR4& v )
 {
  x-=v.x;
  y-=v.y;
  z-=v.z;
  w-=v.w;
  return *this;
 }
//self-multiply
 const VECTOR4& operator *= ( const SCALAR& s )
 {
  x*=s;
  y*=s;
  z*=s;
  w*=s;
  return *this;
 }
//self-divide
 const VECTOR4& operator /= ( const SCALAR& s )
 {
  const SCALAR r = 1 / s;
  x *= r;
  y *= r;
  z *= r;
  w *= r;
  return *this;
 }
//add
 const VECTOR4 operator + ( const VECTOR4& v ) const
 {
  return VECTOR4(x + v.x, y + v.y, z + v.z,w+v.w);
 }
//subtract
 const VECTOR4 operator - ( const VECTOR4& v ) const
 {
  return VECTOR4(x - v.x, y - v.y, z - v.z,w-v.w);
 }
//post-multiply by a scalar
 const VECTOR4 operator * ( const SCALAR& s ) const
 {
  return VECTOR4( x*s, y*s, z*s ,w*s);
 }
//pre-multiply by a scalar
 friend inline const VECTOR4 operator * ( const SCALAR& s, const VECTOR4& v )
 {
  return v * s;
 }
//divide
 const VECTOR4 operator / (SCALAR s) const
 {
  s = 1/s;
  return VECTOR4( s*x, s*y, s*z ,s*w);
 }
////cross product,没有4维叉积
//
// const VECTOR cross( const VECTOR& v ) const
// {
//  //Davis, Snider, "Introduction to Vector Analysis", p. 44
//  return VECTOR( y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x );
// }
//scalar dot product
 const SCALAR dot( const VECTOR4& v ) const
 {
  return x*v.x + y*v.y + z*v.z+w*v.w;
 }
//length
 const SCALAR length() const
 {
  return (SCALAR)sqrt( (double)this->dot(*this) );
 }
//unit vector
 const VECTOR4 unit() const
 {
 return (*this) / length();
 }
//make this a unit vector
 void normalize()
 {
  (*this) /= length();
 }
//equal within an error 慹?
 const bool nearlyEquals( const VECTOR4& v, const SCALAR e ) const
 {
  return fabs(x-v.x)<e && fabs(y-v.y)<e && fabs(z-v.z)<e && fabs(w-v.w)<e;
 }
};
//
// A 4D position
//
//typedef VECTOR4 POINT;
// From gamasutra. This file may follow different licence features.
// A 4x4 matrix
//
class MATRIX4
{
public:
 VECTOR4 C[4]; //column vectors,应该是行向量或列向量,对象占用4*16=64字节的内存空间,内存顺序与真数组的内存顺序是一致的
public:
 MATRIX4()
 {
  //identity matrix
  C[0].x = 1;
  C[1].y = 1;
  C[2].z = 1;
  C[3].w = 1;
 }
 MATRIX4( const VECTOR4& c0, const VECTOR4& c1, const VECTOR4& c2, const VECTOR4& c3 )
 {
  C[0] = c0;
  C[1] = c1;
  C[2] = c2;
  C[3] = c3;
 }
 //index a column, allow assignment
 //NOTE: using this index operator along with the vector index
 //gives you M[column][row], not the standard M[row][column]
 VECTOR4& operator [] ( long i )
 {
  return C[i];
 }
 //compare
 const bool operator == ( const MATRIX4& m ) const
 {
  return C[0]==m.C[0] && C[1]==m.C[1] && C[2]==m.C[2] && C[3]==m.C[3];
 }
 const bool operator != ( const MATRIX4& m ) const
 {
  return !(m == *this);
 }
 //assign
 const MATRIX4& operator = ( const MATRIX4& m )
 {
  C[0] = m.C[0];
  C[1] = m.C[1];
  C[2] = m.C[2];
  C[3] = m.C[3];
  return *this;
 }
 //increment
 const MATRIX4& operator +=( const MATRIX4& m )
 {
  C[0] += m.C[0];
  C[1] += m.C[1];
  C[2] += m.C[2];
  C[3] += m.C[3];
  return *this;
 }
 //decrement
 const MATRIX4& operator -=( const MATRIX4& m )
 {
  C[0] -= m.C[0];
  C[1] -= m.C[1];
  C[2] -= m.C[2];
  C[3] -= m.C[3];
  return *this;
 }
 //self-multiply by a scalar
 const MATRIX4& operator *= ( const SCALAR& s )
 {
  C[0] *= s;
  C[1] *= s;
  C[2] *= s;
  C[3] *= s;
  return *this;
 }
 //self-multiply by a matrix
 const MATRIX4& operator *= ( const MATRIX4& m )
 {
  //NOTE: don抰 change the columns
  //in the middle of the operation
  MATRIX4 temp = (*this);
  C[0] = temp * m.C[0];
  C[1] = temp * m.C[1];
  C[2] = temp * m.C[2];
  C[3] = temp * m.C[3];
  return *this;
 }
 //add
 const MATRIX4 operator + ( const MATRIX4& m ) const
 {
  return MATRIX4( C[0] + m.C[0], C[1] + m.C[1], C[2] + m.C[2], C[3] + m.C[3] );
 }
 //subtract
 const MATRIX4 operator - ( const MATRIX4& m ) const
 {
  return MATRIX4( C[0] - m.C[0], C[1] - m.C[1], C[2] - m.C[2], C[3] - m.C[3]);
 }
 //post-multiply by a scalar
 const MATRIX4 operator * ( const SCALAR& s ) const
 {
  return MATRIX4( C[0]*s, C[1]*s, C[2]*s, C[3]*s );
 }
 //pre-multiply by a scalar
 friend inline const MATRIX4 operator * ( const SCALAR& s, const MATRIX4& m )
 {
  return m * s;
 }
 //post-multiply by a vector
 const VECTOR4 operator * ( const VECTOR4& v ) const
 {
  return( C[0]*v.x + C[1]*v.y + C[2]*v.z+ C[3]*v.w );
 }
 //pre-multiply by a vector
 inline friend const VECTOR4 operator * ( const VECTOR4& v, const MATRIX4& m )
 {
  return VECTOR4( m.C[0].dot(v), m.C[1].dot(v), m.C[2].dot(v), m.C[3].dot(v) );
 }
 //post-multiply by a matrix
 const MATRIX4 operator * ( const MATRIX4& m ) const
 {
  return MATRIX4( (*this) * m.C[0], (*this) * m.C[1], (*this) * m.C[2], (*this) * m.C[3] );
 }
 //transpose
 MATRIX4 transpose() const
 {
  //turn columns on their side
  return MATRIX4( VECTOR4( C[0].x, C[1].x, C[2].x , C[3].x ), //column 0
   VECTOR4( C[0].y, C[1].y, C[2].y, C[3].y ), //column 1
   VECTOR4( C[0].z, C[1].z, C[2].z ,C[3].z), //column 2
   VECTOR4( C[0].w, C[1].w, C[2].w, C[3].w ) //column 3
   );
 }
 ////scalar determinant,没有4维叉积
 //const SCALAR determinant() const
 //{
 // //Lang, "Linear Algebra", p. 143
 // return C[0].dot( C[1].cross(C[2]) );
 //}
 //add by Ivan_han
 const SCALAR det() const
 {
  MATRIX4 mtx=*this;
  SCALAR ret=Bsdet(&mtx[0][0],4);//第一个参数是输入输出参数
  return ret;
 }
 //matrix inverse,去掉返回值类型中的const
 MATRIX4 inverse() const
 {
    MATRIX4 mtx=*this;
    int i=Brinv((SCALAR *)&mtx[0][0],4);
    if(i!=0)
     return mtx;
    return MATRIX4();
 }
 //add by Ivan_han
 friend ostream& operator<< (ostream& os,MATRIX4& mtx);
};
//add by Ivan_han
ostream& operator<< (ostream& os,MATRIX4& mtx)
{
 for(int i=0;i<=3;i++)
 {
  for(int j=0;j<=3;j++)
   os<<mtx[i][j]<<",";
  os<<endl;
 }
 return os;
}
int main(void)
{
   int i,j;
   static float A[4][4]=
   {
    {1,2,3,4},
    {5,6,7,8},
    {9,10,11,12},
    {13,14,15,16}
   };
   static float C[4][4],B[4][4]=
   {
 {1,1,3,4},
 {1,2,3,2},
 {2,4,1,3},
 {5,7,1,4}
   };
   cout<<"----实矩阵乘法----"<<endl;
   Brmul(&A[0][0],&B[0][0],4,4,4,&C[0][0]);
   MATRIX4 mtxA,mtxB,mtxC;
   memcpy(&mtxA,A,sizeof(A));
   memcpy(&mtxB,B,sizeof(B));
   memcpy(&mtxC,C,sizeof(C));
   cout<<mtxA<<endl;
   cout<<mtxB<<endl;
   cout<<mtxC<<endl;
   MATRIX4 mtxD=mtxA.inverse();
   cout<<"----实矩阵求逆----"<<endl;
   cout<<mtxD<<endl;
   cout<<mtxD.inverse()<<endl;
   cout<<"----实矩阵求行列式的值----"<<endl;
   cout<<mtxA.det()<<endl;
   system("pause");
   return 0;
}
四元数(quaternion)模板类的使用
DX中的四元数D3DXQUATERNION和4维向量VECTOR4是兼容的,DX中四元数结构体的四个成员是:
FLOAT x,y,z,w;//w表示数量部分
D3DXQuaternionDot()函数将返回两个四元组的点积
D3DXQuaternionMultiply()函数则将两个四元组相乘。例如:
D3DXQUATERNION Qi(1,0,0,0),Qj(0,1,0,0),Qk(0,0,1,0),Q1(0,0,0,1),Q;
FLOAT fret=D3DXQuaternionDot(&Qi,&Qj);//0
FLOAT fret1=D3DXQuaternionDot(&Qi,&Qi);//1
D3DXQUATERNION* retQ=D3DXQuaternionMultiply(&Q,&Qj,&Qk);//Qk*Qj=-Q_i
D3DXQuaternionNormalize()计算一个单位长度的四元数
D3DXQuaternionLength()计算得到四元组的长度
D3DXQuaternionInverse()共轭变换并规格化四元数(其实就是求逆四元数)
D3DXQuaternionConjugate()求共轭四元数:数量部分w不变,向量部分x,y,z取相反数
例如:
D3DXQUATERNION q8(-1,2,3,2),Q8;
D3DXQUATERNION* retQ8=D3DXQuaternionNormalize(&Q8,&q8);
fret=D3DXQuaternionLength(&q8);//sqrt(18)
fret=D3DXQuaternionLength(&Q8);//1
retQ8=D3DXQuaternionInverse(&Q8,&q8);
retQ=D3DXQuaternionMultiply(&Q,&Q8,&q8);//q8*Q8=[2,(-1,2,3)][1/9,(1/18,-1/9,-1/6)]=[1,(0,0,0)]
retQ=D3DXQuaternionMultiply(&Q,&q8,&Q8);//Q8*q8=[1/9,(1/18,-1/9,-1/6)][2,(-1,2,3)]=[1,(0,0,0)]
retQ8=D3DXQuaternionConjugate(&Q8,&q8);
问题:对于四元数q,q^-1=~q的充要条件是?
四元数模板类的四个成员是:
 private:
  // [w, (x, y, z)],w表示数量部分
  _Tp w, x, y, z;
 cout<<Quaternion<float>(0,1,0,0)*Quaternion<float>(0,0,1,0)<<endl;//[0, (0, 0, 1)],ij=k
 cout<<Quaternion<float>(0,0,1,0)*Quaternion<float>(0,0,0,1)<<endl;//[0, (1, 0, 0)],jk=i
 cout<<Quaternion<float>(0,0,0,1)*Quaternion<float>(0,1,0,0)<<endl;//[0, (0, 1, 0)],ki=j
 cout<<Quaternion<float>(0,0,1,0)*Quaternion<float>(0,1,0,0)<<endl;//[0, (0, 0, -1)],ji=-k
 cout<<Quaternion<float>(0,0,0,1)*Quaternion<float>(0,0,1,0)<<endl;//[0, (-1, 0, 0)],kj=-i
 cout<<Quaternion<float>(0,1,0,0)*Quaternion<float>(0,0,0,1)<<endl;//[0, (0, -1, 0)],ik=-j
 cout<<Quaternion<float>(0,1,0,0)*Quaternion<float>(0,1,0,0)<<endl;//[-1, (0, 0, 0)],i^2=-1
 cout<<Quaternion<float>(0,0,1,0)*Quaternion<float>(0,0,1,0)<<endl;//[-1, (0, 0, 0)],j^2=-1
 cout<<Quaternion<float>(0,0,0,1)*Quaternion<float>(0,0,0,1)<<endl;//[-1, (0, 0, 0)],k^2=-1
 cout<<Quaternion<float>(0,1,0,0)*Quaternion<float>(0,0,1,0)*Quaternion<float>(0,0,0,1)<<endl;//[-1, (0, 0, 0)],ijk=-1
四元数q_1,q_2的乘法:q_1q_2=Re(q_1)Re(q_2)-Im(q_1)·Im(q_2)+Re(q_1)Im(q_2)+Re(q_2)Im(q_1)+Im(q_1)×Im(q_2)
对任意两个四元数q_1,q_2,恒有Re(q_1q_2)=Re(q_2q_1)
对任意两个虚数四元数q_1,q_2(即数量部分为0:Re(q_1)=Re(q_2)=0),恒有q_1q_2+q_2q_1=-2Im(q_1)·Im(q_2)=2Re(q_1q_2)且q_1q_2-q_2q_1=2Im(q_1)×Im(q_2)=2Im(q_1q_2)
定义:四元数~q_1=Re(q_1)-Im(q_1)为四元数q_1=Re(q_1)+Im(q_1)的共轭,则有
Re(q_1)=Re(~q_1),Im(~q_1)=-Im(q_1)
~(~q_1)=q_1
~(q_1+q_2)=~q_1+~q_2,~(q_1q_2)=(~q_2)(~q_1)
~q_1+q_1=2Re(q_1)
当Re(q_1)=0时,~q_1=-q_1
用四元数概念描述3维空间里的旋转运动非常方便。有如下定理:
定理:设有四元数q_1及q_2,则
‖q_1q_2q_1^(-1)‖=‖q_2‖且Re(q_1q_2q_1^(-1))=Re(q_2)
设C^2是全体复数对(z_1,z_2)组成的二元复数集,定义C^2上的加法和乘法运算:
(z_1,z_2)+(z_1',z_2')=(z_1+z_1',z_2+z_2'),(z_1,z_2)(z_1',z_2')=(z_1z_1'-z_2z_2*,z_1z_2'+z_2z_1'*)
证明这样定义的环C^2与四元数除环同构。
1843年,爱尔兰人(19世纪的爱尔兰是英国的一部分)W.R.Hamilton在爱尔兰皇家科学院宣布了四元数的发现,这是历史上发现的第一种乘法交换律不成立的代数——四元数代数。两个三/七维空间中向量的叉积可以用对应的两个四元数的乘积(实部去掉)表示,三维空间中向量的叉积(向量积,三/七维空间特有,不满足交换性、不满足结合性)是一个向量而不是数。具有向量加法和叉积的R^3构成了一个Lie代数(非交换非结合)。
非交换的结合环在19世纪已经发现,那就是四元数(1843)与矩阵(1858),而19世纪末又发现了非结合环——Lie环(1870)。
1844年,Grassmann推演出更有一般性的几类代数。外代数是非交换(反交换、反对称性)、不可除、但结合的代数,外积/楔积a∧b适用于任何R^n,乘法结果是一个“扩张的量”。外代数一定是非交换结合代数;Lie代数不一定是非交换(反交换律)非结合代数。
1853年,(英)哈密顿(W.R.Hamilton,)的《四元数讲义》出版,系统地论述了四元数理论。
1857年,Cayley设计出另一种不可交换的代数——矩阵代数。
他们的研究打开代数的大门。
1870年,Kronecker给出了有限Abel群的抽象定义;
Dedekind开始使用“体”的说法,并研究了代数体;
1871年,哈密顿的学生(英)苏格兰理论物理学家、数学家麦克斯韦 (James Clerk Maxwell ,1831.6.13-1879)分开处理四元数的数量部分和向量部分,创立了向量分析(1871)。
1873年,麦克斯韦的《电磁学》出版,建立了磁场基本方程(麦克斯韦方程)。
1893年,韦伯(H.Weber)定义了抽象的体;
1910年,施坦尼茨展开了体的一般抽象理论;
Dedekind和Kronecker创立了环论;
1910年,施坦尼茨总结了包括群、代数、域等在内的代数体系的研究,开创了代数学。
1920年,埃米·诺特已引入“左模”、“右模”的概念。
1921年,埃米·诺特的《整环的理想理论》是交换代数发展的里程碑。建立了交换Noether环理论,证明了准素分解定理。后又引进交叉积的概念并用决定有限维Galois扩张的布饶尔群。
1927-1935年,Noether研究非交换代数与非交换算术。
1930年,毕尔霍夫建立格论,它源于1847年的bool代数;
二战后,出现了各种代数系统的理论和Bourbaki学派;
1955年,H.Cartan等建立了同调代数理论。
定理(Frobeuius,1878) :实数域R上的可除代数只能是实数域、复数域或四元数除环。
1878年,Frobenius证明基础域R的可除代数(是环,域或者广域上的代数)只有R、C(可交换的结合代数)及四元数体H(无限非交换除环,非交换的结合R-代数)三类,或者表述为:实数域上的所有有限维结合可除代数只有三个。如果去掉结合性要求,则实数域上还有一个可除代数Cayley-Dickson代数,即八卦代数O(非交换、非结合的R-代数)。小皮尔斯也独立得到证明(1881)。
实数域上有限维可除代数,连非结合可除代数也算在内,只有1,2,4,8这四种已知维数(1958)。实数域上有限维的交换可除代数只有实数及复数(1861-1884年K.Weierstrass,1870-1888年Dedekind)。
前苏联数学家盖尔范德的理论:
Banach代数一定是结合的,不一定是交换的,不一定有单位元。从这个意义上说,有单位元的Banach代数只有三种;有单位元的二维欧氏空间(包括实的R^2和复的C^2,后者一般称为酉空间)上的Banach代数本质上只有一种:(a,b)×(c,d)=(ac-bd,ad+bc)。高于四维的Banach代数(属结合代数)必定含有八元数(非结合非交换)
Hamilton的四元数理论与代数基本定理、代数数论的联系:
数强抽象为代数数:~就是满足代数方程(即有理系数多项式方程)的复数(又根据伽罗瓦理论,代数数不一定能用根式表示出来)。
例如,按定义,某些实数、某些复数是代数数,超越数和四元数i,j,k就不是代数数。
四元数除环H的定义:含有复数域C和i,j,k的除环。
x^2+1=0在H中有无穷多个根,四元数i,j,k显然是其根,但不是代数数。
整数[普通整数/有理整数:即正负自然数和零]弱抽象为代数整数[还是不简称为好]:如果一个代数数满足的多项式方程是首一的(即最高次项系数为1),系数是整数,则称为~。
与有限群论的联系:
在非阿贝尔群中,阶数为8的四元数群的所有子群是正规子群。
阶数为60的二十面体群不具有真正规子群。
威廉·罗文·哈密尔顿希望这种广义复数能用来表示三维空间的旋转,象复数能用来表示平面的旋转一样。
四元数就是1,i,j,k这四个单位的线性组合。这些新复数的确可以表示三维空间中的旋转(也可以表示四维空间中的旋转)。
因为三维空间中的旋转是非交换的。因此四元数单位是非交换的这个结果并不出人意外。
四元数群Q的8个元素是:1=I,-1=a^2,i=a,-i=a^3,j=b,-j=b^3,k=ab,-k=ba
抽象的哈密尔顿群的定义:任何非阿贝尔群如其所有子群都是正规子群就称为哈密尔顿群。
四元数群是阶数最小(8阶)的哈密尔顿群。
Quaternion class test
Constructors:
q1=[0, (0, 0, 0)]
q2=[1, (2, 3, 4)]
q3=[1, (2, 3, 4)]
q4=[5, (6, 7, 8)]
Operators:
Operator =
q5 = [1, (2, 3, 4)]
Operator +
q5 + q4 = [6, (8, 10, 12)]
Operator -
q5 - q4 = [-4, (-4, -4, -4)]
Operator *
q7  * q8 = [8, (-9, -2, 11)]
Operator /
q7/(q8.inverse) = [8, (-9, -2, 11)]
Operator +=
q4 += q5 is [6, (8, 10, 12)]
Operator -=
q5 -= q5 is [0, (0, 0, 0)]
Operator *=
q7 *= q8 is [8, (-9, -2, 11)]
Operator /=
q7 /= q8.inverse() is [8, (-9, -2, 11)]
Operator !=
works!
Operator ==
works!
Norm of q2 = 30
Magnitude of q2 = 5.47723
Scale of q2 by 2 = [2, (4, 6, 8)]
Inverse of q8 = [0.111111, (0.0555556, -0.111111, -0.166667)]
Conjugate of q8 = [2, (1, -2, -3)]
Unit Quaternion of q8 is [0.471405, (-0.235702, 0.471405, 0.707107)]
Rotate q8 by 1.1, 2.34, 7.65 = -1.71889, 7.02889, 3.58444
[-1.28978e-008, (-1.71889, 7.02889, 3.58444)]
#include "stdafx.h"
#include "quaternion.h"//四元数模板类的声明与定义都放在这个文件里
 
int main(int argc, char **argv) 

 // Quaternion test class  
 cout << "Quaternion class test" << endl; 
 cout << "Constructors:" << endl; 
 float vect[4] = { 5, 6, 7, 8 }; 
 float v[3]= { 1.1, 2.34, 7.65 }; 
 Quaternion<float> q1; 
 Quaternion<float> q2(1.0f, 2.0f, 3.0f, 4.0f);
 Quaternion<float> q3(q2); 
 Quaternion<float> q4(vect); 
 Quaternion<float> q7(3.0f, 1.0f, -2.0f, 1.0f); 
 Quaternion<float> q8(2.0f, -1.0f, 2.0f, 3.0f); 
 Quaternion<float> q9(3.0f, 1.0f, -2.0f, 1.0f); 
 Quaternion<float> q16(0.0f, 1.1f, 2.34f, 7.65f); 
 // 
   cout << "q1=" << q1 << endl; 
   cout << "q2=" << q2 << endl; 
   cout << "q3=" << q3 << endl; 
   cout << "q4=" << q4 << endl; 
  
   cout << "Operators:" << endl; 
   cout << "Operator =" << endl; 
   Quaternion <float> q5 = q2;
   cout << "q5 = " << q5 << endl; 
   cout << "Operator +" << endl; 
   Quaternion <float> q6 =  q5 + q4; 
   cout << "q5 + q4 = " << q6 << endl;  //should equal (6,8,10,12)  
   cout << "Operator -" << endl; 
   q6 = q5 - q4; 
   cout << "q5 - q4 = " << q6 << endl;  //should equal (-4,-4,-4,-4)  
   cout << "Operator *" << endl; 
   q6 = q7 * q8; 
   cout << "q7  * q8 = " << q6 << endl; //should equal (8,-9,-2,11)   
   cout << "Operator /" << endl; 
   q6 = q8.inverse(); 
   cout << "q7/(q8.inverse) = " << q7/q6 << endl;//should equal [8, (-9, -2, 11)]  
   cout << "Operator += " << endl; 
   q4 += q5; 
   cout << "q4 += q5 is " << q4 << endl;//should equal [6, (8, 10, 12)]  
   cout << "Operator -= " << endl; 
   q5 -= q5; 
   cout << "q5 -= q5 is " << q5 << endl;//should equal [0, (0, 0, 0)]  
   cout << "Operator *= " << endl; 
   q7 *= q8; 
   cout << "q7 *= q8 is " << q7 << endl;//should equal [8, (-9, -2, 11)]  
   cout << "Operator /= " << endl; 
   q7= q9; 
   q6 = q8.inverse(); 
   q7/=q6; 
   cout << "q7 /= q8.inverse() is " << q7 << endl;//should equal [8, (-9, -2, 11)]  
   cout << "Operator != " << endl; 
   if (q2 != q2) 
     cout << "doesn't work:(" << endl; 
   else 
     cout << "works!" << endl; 
   cout << "Operator == " << endl; 
   if (q2 == q2) 
     cout << "works!" << endl; 
   else 
     cout << "doesn't work:(" << endl; 
   cout << "Norm of q2 = " << q2.norm() << endl; //30  
   cout << "Magnitude of q2 = " << q2.magnitude() << endl; //5.4772255....  
   q6 = q2.scale(2); 
   cout << "Scale of q2 by 2 = " << q6 << endl;//should equal [2, (4, 6, 8)]  
   cout << "Inverse of q8 = " << q8.inverse() << endl;//should equal [0.111..., (0.0555..., -0.111..., -0.1666...)]  
   cout << "Conjugate of q8 = " << q8.conjugate() <<endl;  //should equal (2,1,-2,-3)  
   cout << "Unit Quaternion of q8 is " << q8.UnitQuaternion() << endl; 
   //QuatRot   
   q8.QuatRotation(v); 
   cout << "Rotate q8 by 1.1, 2.34, 7.65 = " << v[0] << ", " << v[1] << ", " << v[2] << endl; 
    //should get the same answer as QuatRot(v, q8) ignoring the w factor  
   q2=q8*q16; 
   q3=q2*(q8.inverse()); 
   cout << q3 << endl; 
  
 #ifdef SHOEMAKE  
   float v1[3] = { 2.3f, 3.2f, 4.3f }; 
   cout << "\nEuler -> Quaternion convertion test:" << endl; 
   cout << " -in vector: (" << v1[0] << ", " << v1[1] << ", " << v1[2] << ")" << endl; 
   Quaternion <float> q10(v1, EulOrdZYXs); 
   cout << " -out quaternion: " << q10 << endl; 
   cout << "Quaternion -> Euler convertion test:" << endl; 
   cout << " -in quaternion: " << q10 << endl; 
   q10.toEuler(v1, EulOrdZYXs); 
   cout << " -out vector: (" << v1[0] << ", " << v1[1] << ", " << v1[2] << ")" << endl; 
 #endif
 system("pause");
 return 0;
}
0 0
原创粉丝点击