作者:朱金燦
來源:http://blog.csdn.net/clever101/
最近在看《3D數學基礎:圖形與遊戲開發》。該書第六章實現了一個簡單三維向量類。我看了一下代碼,發現有些地方是錯的,於是做了一些小修改。該三維向量類實現了一些常用的向量運算,如點乘、叉乘等。對此不熟悉的同學可以參考相關線性代數教材。現把源碼貼上:
#include <float.h><br />//@brief 浮點數比較宏,採用VC的浮點數單精確度FLT_EPSILON<br />#define FLOAT_EQ(x,v) (((v - FLT_EPSILON) < x) && (x <( v + FLT_EPSILON)))<br />namespace TD_Math<br />{<br /> class Vector3<br /> {<br /> public:<br />float x;<br />float y;<br />float z;<br /> //@brief 預設建構函式,不執行任何操作<br /> Vector3()<br /> {<br /> zero();// 預設為零向量<br /> }<br /> //@brief 複製建構函式<br /> Vector3(const Vector3 &a):x(a.x),y(a.y),z(a.z){}<br /> //@brief 帶參數的建構函式,用三個值完成初始化<br /> Vector3(float fx,float fy,float fz):x(fx),y(fy),z(fz){}<br /> //@brief 重載複製運算子,並返回引用,以實現左值<br /> Vector3& operator = (const Vector3 &a)<br /> {<br /> x = a.x;<br /> y = a.y;<br /> z = a.z;<br /> }</p><p> //@brief 重載“==”操作符<br /> bool operator ==(const Vector3 &a)const<br /> { return (FLOAT_EQ(x,a.x)&&FLOAT_EQ(y,a.y)&&FLOAT_EQ(z,a.z)); }<br /> //@brief 重載“!=”運算子<br /> bool operator !=(const Vector3 &a)const<br />{<br />return ((!FLOAT_EQ(x,a.x))||(!FLOAT_EQ(y,a.y))||(!FLOAT_EQ(z,a.z)));<br />}<br />//@brief 置為零向量<br />void zero(){x = y = z = 0.0f;}<br />//@brief 重載“-”運算子<br />Vector3 operator - () const {return Vector3(-x,-y,-z);}</p><p> //@brief 重載二元“+”運算子<br />Vector3 operator +(const Vector3 &a) const<br />{<br />return Vector3(x+a.x,y+a.y,z+a.z);<br />}<br /> //@brief 重載二元“-”運算子<br /> Vector3 operator -(const Vector3 &a)const<br />{<br />return Vector3(x-a.x,y-a.y,z-a.z);<br />}<br />//@brief 與標量的乘法<br />Vector3 operator *(float a)const<br />{<br />return Vector3(x*a,y*a,z*a);<br />}<br />//@brief 與標量的除法<br />Vector3 operator /(float a)const<br />{<br />float oneOverA = 1.0f/a; // 注意:這裡不對“除零”進行檢查<br />return Vector3(x*oneOverA,y*oneOverA,z*oneOverA);<br />}<br />//@brief 重載自反運算子<br />Vector3& operator +=(const Vector3 &a)<br />{<br /> x += a.x;<br /> y += a.y;<br /> z += a.z;<br /> return *this;<br />}<br />Vector3& operator -=(const Vector3 &a)<br />{<br />x -= a.x;<br />y -= a.y;<br />z -= a.z;<br />return *this;<br />}<br />Vector3& operator *=(float a)<br />{<br />x*=a;<br />y*=a;<br />z*=a;<br />return *this;<br />}<br />Vector3& operator /=(float a)<br />{<br />float oneOverA = 1.0f/a;<br />x*=oneOverA;<br />y*=oneOverA;<br />z*=oneOverA;<br />return *this;<br />}<br /> //@brief 向量標準化<br />void normalize()<br />{<br />float magsq = x*x+y*y+z*z;<br />if (magsq>0.0f) // 檢查除零<br />{<br />float oneOverMag = 1.0f/sqrt(magsq);<br />x *=oneOverMag;<br />y *=oneOverMag;<br />z *=oneOverMag;<br />}<br />}<br />//@brief 向量點乘<br />float operator *(const Vector3 &a)const<br />{<br />return (x*a.x+y*a.y+z*a.z);<br />}<br /> };<br />// 非成員函數<br />//@brief 求向量模<br />inline float vectorMag(const Vector3 &a)<br />{<br />return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);<br />}<br />//@brief 計算兩向量的叉乘<br />inline Vector3 crossProduct(const Vector3 &a,const Vector3 &b)<br />{<br />return Vector3(<br />a.y*b.z-a.z*b.y,<br />a.z*b.x-a.x*b.z,<br />a.x*b.y-a.y*b.x<br />);<br />}<br />//@brief 實現標量左乘<br />inline Vector3 operator *(float k,const Vector3 &v)<br />{<br />return Vector3(k*v.x,k*v.y,k*v.z);<br />}<br />//@brief 計算兩點間距離<br />inline float distance(const Vector3 &a,const Vector3 &b)<br />{<br />float dx = a.x-b.x;<br />float dy = a.y-b.y;<br />float dz = a.z-b.z;<br />return sqrt(dx*dx+dy*dy+dz*dz);<br />}<br />//@brief 提供一個全域零向量<br />extern const Vector3 kZeroVector;<br />}<br />
參考文獻:
1. 3D數學基礎:圖形與遊戲開發,作者: 鄧恩,譯者: 陳洪 / 史銀雪 / 王榮靜