Small World: 精简向量运算库
来源:互联网 发布:js判断奇数偶数 编辑:程序博客网 时间:2024/06/07 17:26
第四章: 工欲善其事必先利其器
上一章,回顾了物理引擎中需要的物理学知识,为了能在系统中对其进行数值计算,还需要最基本的向量运算库,如表示二维或三维空间中的点,矩阵运算,四元数等。最少我需要一下几种功能:
1.多维向量表示及其运算,如叉乘,点积,加减等;
2.二至四维的矩阵,及其运算;
3.三或四维矩阵表示的转移矩阵,进行向量的平移,旋转,缩放;
4.四元数的操作以及转换。
目前只需要以上几种运算,所以使用其他的向量库未免太多复杂而且又难以满足,系统对不同维度变化的需求,所以我准备写了一个精简的向量运算库,目前还在不断改进,代码存在:https://github.com/lxdfigo/SimpleMath 网站上。
第一节 向量
首先,我需要一个维度可变的向量,因为物理引擎需要适应三维和二维两种系统。所以,可以使用模版类对向量维数进行控制,基本方法如下:
template<class T, int DIMENSION>class CVector{private:T Elements[DIMENSION];public:CVector(T f = 0);CVector(T v1, T v2);CVector(T v1, T v2, T v3, ...);CVector(const CVector<int,DIMENSION>& vec);CVector(const CVector<float,DIMENSION>& vec);CVector(const CVector<double,DIMENSION>& vec);bool operator<(const CVector& Vector) const;bool operator>(const CVector& Vector) const;CVector& operator=(const CVector& Vector);CVector operator+(const CVector& Vector) const;inline CVector operator-(const CVector& Vector) const;CVector operator* (T ccalar) const;CVector operator/ (T ccalar) const;CVector operator* (const CVector& Vector) const;CVector operator/ (const CVector& Vector) const;CVector& operator+=(const CVector& Vector);CVector& operator-=(const CVector& Vector);CVector& operator*=(T ccalar);CVector& operator/=(T ccalar);inline T & operator [] (int i) { return Elements[i]; }inline T operator [] (int i) const { return Elements[i]; }inline T Length() const;inline T Length2() const;inline T Dot(const CVector& Vector) const;T Distance(const CVector& Vector) const;T SquaredDistance(const CVector& Vector) const;void Normalize();void UniformRandomHyperSphere(T rng );T minElement();T maxElement();void setAll(T v);void zero();};
模版参数T控制类型,DIMENSION给出向量维度,其构造函数有三种,当只有一个参数时,赋给所有元素,当有两个或两个以上参数时,按顺序赋给所有元素。根据系统需要,定义了以下几种常用类型:
typedef CVector<float,2> Vec2f;typedef CVector<double,2> Vec2d;typedef CVector<float,3> Vec3f;typedef CVector<double,3> Vec3d;typedef CVector<float,4> Vec4f;typedef CVector<double,4> Vec4d;
第二节 矩阵
根据n维向量,可以定义n x n维的矩阵,同样通过模版参数对维度和类型进行控制,定义如下:
template<class T, int DIMENSION>class CMatrix{private:CVector<T,DIMENSION> Rows[DIMENSION];public:CMatrix(){}inline CVector<T,DIMENSION> & operator [] (int i) { return Rows[i]; }inline CVector<T,DIMENSION> operator [] (int i) const { return Rows[i]; }CVector<T,DIMENSION> operator * (CVector<T,DIMENSION> &vec);CMatrix operator * (const CMatrix &mat);CMatrix operator * (T scale);CMatrix operator / (T scale);CMatrix operator + (const CMatrix &mat);CMatrix operator - (const CMatrix &mat);CMatrix& operator += (const CMatrix& mat);CMatrix& operator -= (const CMatrix& mat);CMatrix& operator *= (const CMatrix& mat);CMatrix& operator *= (T scale);CMatrix& operator/=(T scale);void zero();};
矩阵运算包括简单的加减,矩阵乘法,矩阵和向量的乘积等。还有矩阵清零的函数,定义常用矩阵如下:
typedef CMatrix<float,2> Mat2x2f;typedef CMatrix<float,3> Mat3x3f;typedef CMatrix<float,4> Mat4x4f;typedef CMatrix<double,3> Mat3x3d;typedef CMatrix<double,4> Mat4x4d;
根据矩阵类型和操作,定义空间变换需要的转移矩阵类型:
template<class T, int DIMENSION>class CTransform{private:CMatrix<T,DIMENSION> mat;public:CTransform();~CTransform(){}void reset();CTransform& makeMoveTrans(CVector<T,DIMENSION-1>& vec);CTransform& makeScaleTrans(CVector<T,DIMENSION-1>& vec);CTransform& makeRotateTrans(Quat<T>& quat);CVector<T,DIMENSION-1>& trans(CVector<T,DIMENSION-1>& vec);};typedef CTransform<double,3> Trans3x3d;typedef CTransform<float,3> Trans3x3f;typedef CTransform<double,4> Trans4x4d;typedef CTransform<float,4> Trans4x4f;
转移矩阵一般情况下是单位矩阵,根据需要移动的向量和角度的不同可以make成不懂的矩阵。通过trans对向量进行操作。
第三节 四元数
为了避免万向锁问题(即利用欧拉角进行物体旋转时,当第二个角是+-90度时,第一个轴被旋转到和第三个平行,导致失去了一个旋转的自由度,只能进行两个轴的旋转),引入四元数解决这一问题。详细情况google一下,你就知道。
定义四元数的基本操作:
template<class T>class Quat{public:T Elements[4]; inline Quat() { Elements[0]=0.0; Elements[1]=0.0; Elements[2]=0.0; Elements[3]=1.0; }inline Quat( T x, T y, T z, T w );inline Quat( const CVector<T,4>& v );inline Quat( T angle, const CVector<T,3>& axis);inline Quat& operator = (const Quat& v);inline bool operator == (const Quat& v) const;inline bool operator != (const Quat& v) const;inline bool operator < (const Quat& v) const;inline void set(T x, T y, T z, T w);inline T & operator [] (int i) { return Elements[i]; }inline T operator [] (int i) const { return Elements[i]; }inline T & x() { return Elements[0]; }inline T & y() { return Elements[1]; }inline T & z() { return Elements[2]; }inline T & w() { return Elements[3]; }inline T x() const { return Elements[0]; }inline T y() const { return Elements[1]; }inline T z() const { return Elements[2]; }inline T w() const { return Elements[3]; }inline const Quat operator * (T rhs) const;inline Quat& operator *= (T rhs);inline const Quat operator*(const Quat& rhs) const;inline const Quat operator*(const CVector<T,3>& rhs) const;inline Quat& operator*=(const Quat& rhs);inline Quat operator / (T rhs) const;inline Quat& operator /= (T rhs);inline const Quat operator/(const Quat& denom) const;inline Quat& operator/=(const Quat& denom);inline const Quat operator + (const Quat& rhs) const;inline Quat& operator += (const Quat& rhs);inline const Quat operator - (const Quat& rhs) const;inline Quat& operator -= (const Quat& rhs);inline const Quat operator - () const;T Dot(const Quat& rhs) const;T length() const;T length2() const;inline Quat conj () const;inline const Quat inverse () const;void makeRotate (T angle, T x, T y, T z );void makeRotate ( T angle, const CVector<T,3>& vec );void makeRotate( const CVector<T,3>& vec1, const CVector<T,3>& vec2 );void getRotate ( T & angle, T & x, T & y, T & z ) const;void getRotate ( T & angle, CVector<T,3>& vec ) const;void slerp(T t, const Quat& from, const Quat& to);CVector<T,3> rotate (const CVector<T,3>& vec ) const;}; typedef Quat<float> Quatf;typedef Quat<double> Quatd;
四元数的操作较为复杂,根据向量或是轴和角的组合来构造,只能和三维向量进行运算,是对三维空间旋转进行操作的类。
有了这三种基本类型,就可以处理二维和三维系统中简单的平移,旋转操作了。
- Small World: 精简向量运算库
- Small World Theory
- Small-World Model
- Explanation of Small World Phenomenon
- 向量运算
- 向量运算
- 向量运算
- power law,small world,bow-tie理论
- 小世界网络 Small-world networks
- Small World:如何写物理引擎
- 精简的大数运算
- 位运算--hdu5980 Find Small A
- matlab 向量/矩阵运算
- 向量坐标运算
- 了解向量运算
- Unity3D -- 图形 -- 向量运算
- 向量及其运算
- 空间向量坐标运算
- 页面有100个button,一个listbox。动态产生控件及一些逻辑控制
- 巧用同余定理
- windows操作系统的自启动项
- 福音!JS脚本可视化调试支持——基于Google v8引擎的脚本调试
- c# 标准控件 缩写
- Small World: 精简向量运算库
- HDOJ 2072
- JMAP、jstat命令输出结果说明
- Keil MDK 编译出现的警告和错误解决
- Unix 进程 线程 函数类比
- PHP学习
- 第1章--软件构建的世界
- C#程序设计(二十二)----显示一副图片
- c语言预处理命令