vector的实现

转自:http://blog.csdn.net/clever101/

 


      最近在看《3D数学基础:图形与游戏开发》。该书第六章实现了一个简单三维向量类。我看了一下代码,发现有些地方是错的,于是做了一些小修改。该三维向量类实现了一些常用的向量运算,如点乘、叉乘等。对此不熟悉的同学可以参考相关线性代数教材。现把源码贴上:

 


view plaincopy to clipboardprint?
#include <float.h>  
//@brief 浮点数比较宏,采用VC的浮点数单精度FLT_EPSILON  
#define FLOAT_EQ(x,v) (((v - FLT_EPSILON) < x) && (x <( v + FLT_EPSILON)))  
namespace TD_Math  
{  
    class Vector3  
    {  
    public:  
        float x;  
        float y;  
        float z;  
     //@brief 默认构造函数,不执行任何操作  
     Vector3()  
     {  
         zero();// 默认为零向量  
     }  
     //@brief 复制构造函数  
     Vector3(const Vector3 &a):x(a.x),y(a.y),z(a.z){}  
     //@brief 带参数的构造函数,用三个值完成初始化  
     Vector3(float fx,float fy,float fz):x(fx),y(fy),z(fz){}  
     //@brief 重载复制运算符,并返回引用,以实现左值  
     Vector3& operator = (const Vector3 &a)  
     {  
         x = a.x;  
         y = a.y;  
         z = a.z;  
     }  
   
     //@brief 重载“==”操作符  
     bool operator ==(const Vector3 &a)const 
     { return (FLOAT_EQ(x,a.x)&&FLOAT_EQ(y,a.y)&&FLOAT_EQ(z,a.z)); }  
    //@brief 重载“!=”运算符  
    bool operator !=(const Vector3 &a)const 
    {  
        return ((!FLOAT_EQ(x,a.x))||(!FLOAT_EQ(y,a.y))||(!FLOAT_EQ(z,a.z)));   
    }  
    //@brief 置为零向量  
    void zero(){x = y = z = 0.0f;}  
    //@brief 重载“-”运算符  
    Vector3 operator - () const {return Vector3(-x,-y,-z);}  
    
    //@brief 重载二元“+”运算符  
    Vector3 operator +(const Vector3 &a) const 
    {  
        return Vector3(x+a.x,y+a.y,z+a.z);  
    }  
    //@brief 重载二元“-”运算符  
    Vector3 operator -(const Vector3 &a)const 
    {  
        return Vector3(x-a.x,y-a.y,z-a.z);  
    }  
    //@brief 与标量的乘法  
    Vector3 operator *(float a)const 
    {  
        return Vector3(x*a,y*a,z*a);  
    }  
    //@brief 与标量的除法  
    Vector3 operator /(float a)const 
    {  
        float oneOverA = 1.0f/a; // 注意:这里不对“除零”进行检查  
        return Vector3(x*oneOverA,y*oneOverA,z*oneOverA);  
    }  
    //@brief 重载自反运算符  
    Vector3& operator +=(const Vector3 &a)  
    {  
       x += a.x;  
       y += a.y;  
       z += a.z;  
       return *this;  
    }  
    Vector3& operator -=(const Vector3 &a)  
    {  
        x -= a.x;  
        y -= a.y;  
        z -= a.z;  
        return *this;  
    }  
    Vector3& operator *=(float a)  
    {  
        x*=a;  
        y*=a;  
        z*=a;  
        return *this;  
    }  
    Vector3& operator /=(float a)  
    {  
        float oneOverA = 1.0f/a;  
        x*=oneOverA;  
        y*=oneOverA;  
        z*=oneOverA;  
        return *this;  
    }  
    //@brief 向量标准化  
    void normalize()  
    {  
        float magsq = x*x+y*y+z*z;  
        if (magsq>0.0f) // 检查除零  
        {  
            float oneOverMag = 1.0f/sqrt(magsq);  
            x *=oneOverMag;  
            y *=oneOverMag;  
            z *=oneOverMag;  
        }  
    }  
    //@brief 向量点乘  
    float operator *(const Vector3 &a)const 
    {  
        return (x*a.x+y*a.y+z*a.z);  
    }  
    };  
    // 非成员函数  
    //@brief 求向量模  
    inline float vectorMag(const Vector3 &a)  
    {  
        return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);  
    }  
    //@brief 计算两向量的叉乘  
    inline Vector3 crossProduct(const Vector3 &a,const Vector3 &b)  
    {  
        return Vector3(  
            a.y*b.z-a.z*b.y,  
            a.z*b.x-a.x*b.z,  
            a.x*b.y-a.y*b.x  
            );  
    }  
    //@brief 实现标量左乘  
    inline Vector3 operator *(float k,const Vector3 &v)  
    {  
        return Vector3(k*v.x,k*v.y,k*v.z);  
    }  
    //@brief 计算两点间距离  
    inline float distance(const Vector3 &a,const Vector3 &b)  
    {  
        float dx = a.x-b.x;  
        float dy = a.y-b.y;  
        float dz = a.z-b.z;  
        return sqrt(dx*dx+dy*dy+dz*dz);  
    }  
    //@brief 提供一个全局零向量  
    extern const Vector3 kZeroVector;  

#include <float.h>
//@brief 浮点数比较宏,采用VC的浮点数单精度FLT_EPSILON
#define FLOAT_EQ(x,v) (((v - FLT_EPSILON) < x) && (x <( v + FLT_EPSILON)))
namespace TD_Math
{
    class Vector3
    {
    public:
  float x;
  float y;
  float z;
     //@brief 默认构造函数,不执行任何操作
  Vector3()
  {
   zero();// 默认为零向量
  }
  //@brief 复制构造函数
  Vector3(const Vector3 &a):x(a.x),y(a.y),z(a.z){}
  //@brief 带参数的构造函数,用三个值完成初始化
  Vector3(float fx,float fy,float fz):x(fx),y(fy),z(fz){}
     //@brief 重载复制运算符,并返回引用,以实现左值
  Vector3& operator = (const Vector3 &a)
  {
   x = a.x;
   y = a.y;
   z = a.z;
  }
 
     //@brief 重载“==”操作符
  bool operator ==(const Vector3 &a)const
  { return (FLOAT_EQ(x,a.x)&&FLOAT_EQ(y,a.y)&&FLOAT_EQ(z,a.z)); }
    //@brief 重载“!=”运算符
    bool operator !=(const Vector3 &a)const
 {
  return ((!FLOAT_EQ(x,a.x))||(!FLOAT_EQ(y,a.y))||(!FLOAT_EQ(z,a.z)));
 }
 //@brief 置为零向量
 void zero(){x = y = z = 0.0f;}
 //@brief 重载“-”运算符
 Vector3 operator - () const {return Vector3(-x,-y,-z);}
 
    //@brief 重载二元“+”运算符
 Vector3 operator +(const Vector3 &a) const
 {
  return Vector3(x+a.x,y+a.y,z+a.z);
 }
    //@brief 重载二元“-”运算符
    Vector3 operator -(const Vector3 &a)const
 {
  return Vector3(x-a.x,y-a.y,z-a.z);
 }
 //@brief 与标量的乘法
 Vector3 operator *(float a)const
 {
  return Vector3(x*a,y*a,z*a);
 }
 //@brief 与标量的除法
 Vector3 operator /(float a)const
 {
  float oneOverA = 1.0f/a; // 注意:这里不对“除零”进行检查
  return Vector3(x*oneOverA,y*oneOverA,z*oneOverA);
 }
 //@brief 重载自反运算符
 Vector3& operator +=(const Vector3 &a)
 {
    x += a.x;
    y += a.y;
    z += a.z;
    return *this;
 }
 Vector3& operator -=(const Vector3 &a)
 {
  x -= a.x;
  y -= a.y;
  z -= a.z;
  return *this;
 }
 Vector3& operator *=(float a)
 {
  x*=a;
  y*=a;
  z*=a;
  return *this;
 }
 Vector3& operator /=(float a)
 {
  float oneOverA = 1.0f/a;
  x*=oneOverA;
  y*=oneOverA;
  z*=oneOverA;
  return *this;
 }
    //@brief 向量标准化
 void normalize()
 {
  float magsq = x*x+y*y+z*z;
  if (magsq>0.0f) // 检查除零
  {
   float oneOverMag = 1.0f/sqrt(magsq);
   x *=oneOverMag;
   y *=oneOverMag;
   z *=oneOverMag;
  }
 }
 //@brief 向量点乘
 float operator *(const Vector3 &a)const
 {
  return (x*a.x+y*a.y+z*a.z);
 }
    };
 // 非成员函数
 //@brief 求向量模
 inline float vectorMag(const Vector3 &a)
 {
  return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
 }
 //@brief 计算两向量的叉乘
 inline Vector3 crossProduct(const Vector3 &a,const Vector3 &b)
 {
  return Vector3(
   a.y*b.z-a.z*b.y,
   a.z*b.x-a.x*b.z,
   a.x*b.y-a.y*b.x
   );
 }
 //@brief 实现标量左乘
 inline Vector3 operator *(float k,const Vector3 &v)
 {
  return Vector3(k*v.x,k*v.y,k*v.z);
 }
 //@brief 计算两点间距离
 inline float distance(const Vector3 &a,const Vector3 &b)
 {
  float dx = a.x-b.x;
  float dy = a.y-b.y;
  float dz = a.z-b.z;
  return sqrt(dx*dx+dy*dy+dz*dz);
 }
 //@brief 提供一个全局零向量
 extern const Vector3 kZeroVector;
}
 


参考文献:

 


1. 3D数学基础:图形与游戏开发,作者: 邓恩,译者: 陈洪 / 史银雪 / 王荣静

 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clever101/archive/2010/11/30/6046662.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值