数学基础知识及函数

向量

      只用大小就能表示的量叫数量,比如温度,质量等。既需要用大小表示,同时还要指明方向的量叫向量,比如位移,速度等。几何学中,我们用有向线段来表示向量。有两个变量可以确定一个向量,即向量的长度和向量的方向。量与位置无关,有相同长度和方向的两个向量是相等的。

理解:一般可以用三维向量表示一个空间点位置,但为了能够将物体的位移、旋转、放缩用一个向量就进行运算,所以有些使用了四维向量,即vector4

 

左右手坐标系

一图胜前言,不懂怎么用手扭曲的去比划的看看图,就明白啥是左手,啥是右手坐标系了。在OpenGL中使用的是右手坐标系,DirectX,Irrlicht中使用的是左手坐标系。(图片来自于网络)

向量的模

向量的大小(或长度)称为向量的模,向量a的模记为||a||。下面以3维的向量(3D中用的最多)为例:abc2_html_8d5f713

理解:如果用四维或三维向量表示一个空间点,那么模就是该点到零点的距离。

如果有两个点,那么模就是两点之间的直线距离(distance).

程序算法:

T getLength() const{returncore::squareroot(X*X+Y*Y+Z*Z); }/

T getLengthSQ() const{returnX*X+Y*Y+Z*Z; }

 

三维空间中两点的距离

公式:abc4_html_m257962b9

 

程序算法:

T getDistanceFrom(constvector3d<T>&other)const{returnvector3d<T>(X-other.X,Y-other.Y,Z-other.Z).getLength();}

 

向量的规范化

向量的规范化也称(归一化)就是使向量的模变为1,即变为单位向量。可以通过将向量都除以该向量的模来实现向量的规范化。规范化后的向量相当于与向量同方向的单位向量,可以用它表示向量的方向。由于方向的概念在3D编程中非常重要,所以此概念也很重要,单位向量有很多重要的性质,在表示物体表面的法线向量时用的更是频繁。

基本的公式: clip_image002

程序算法:

vector3d<T>&normalize(){f64 length= (f32)(X*X+Y*Y+Z*Z);if(core::equals(length, 0.0)) 

return *this; length = core::reciprocal_squareroot( (f64) (X*X+Y*Y+Z*Z) );

X = (T)(X*length);

Y = (T)(Y*length);

Z = (T)(Z*length);

return *this;}

 

上述代码中首先计算length以防其为0,然后直接计算1/||u||,(这样做的目的从代码实现上来看是因为SSE,Nviadia都有可以直接计算此值的能力) 然后再分别与各坐标值进行乘法运算。

向量的加减法,数乘

太简单,不多描述,无非就是对应的加,减,乘罢了,几何意义讲一下,加法可以看做是两个向量综合后的方向,减法可以看做两个向量的差异方向(甚至可以用于追踪算法),数乘用于对向量进行缩放。

为了完整,这里从百度百科拷贝一段资料过来:(以下都是2维的,放到3维也差不多)

a=(x,y),b=(x',y')。

1、向量的加法


向量的加法满足平行四边形法则和三角形法则。

AB+BC=AC

a+b=(x+x',y+y')。

a+0=0+a=a。

向量加法的运算律:

交换律:a+b=b+a;

结合律:(a+b)+c=a+(b+c)。

理解:加减法只是单纯的向量位移。

2、向量的减法


如果ab是互为相反的向量,那么a=-bb=-aa+b=0. 0的反向量为0

AB-AC=CB. 即“共同起点,指向被减”

a=(x,y) b=(x',y') 则 a-b=(x-x',y-y').

3、数乘向量


实数λ和向量a的乘积是一个向量,记作λa,且∣λa∣=∣λ∣·∣a∣。

当λ>0时,λaa同方向;

当λ<0时,λaa反方向;

当λ=0时,λa=0,方向任意。

a=0时,对于任意实数λ,都有λa=0

注:按定义知,如果λa=0,那么λ=0或a=0

实数λ叫做向量a的系数,乘数向量λa的几何意义就是将表示向量a的有向线段伸长或压缩。

当∣λ∣>1时,表示向量a的有向线段在原方向(λ>0)或反方向(λ<0)上伸长为原来的∣λ∣倍;

当∣λ∣<1时,表示向量a的有向线段在原方向(λ>0)或反方向(λ<0)上缩短为原来的∣λ∣倍。

数与向量的乘法满足下面的运算律

结合律:(λa)·b=λ(a·b)=(a·λb)。

向量对于数的分配律(第一分配律):(λ+μ)aaa.

数对于向量的分配律(第二分配律):λ(a+b)=λab.

数乘向量的消去律:① 如果实数λ≠0且λa=λb,那么a=b。② 如果a0且λa=μa,那么λ=μ。

理解:数乘向量即为对向量进行固定放缩,但是整体放缩,而不是某一轴向的放缩。

 

点积(dot product)又称数量积或内积

v0 . v1 = v0.x*v1.x+v0.y*v1.y+v0.z*v1.z;
所以向量的点积结果是一个数,而非向量。
点积等于向量v0的长度乘以v1的长度,再乘以它们之间夹角的余弦,即|v0|*|v1|*cos(θ).
通过点积,可以计算两个向量之间的夹角。
cos(θ)=v0.v1/|v0||v1|;
θ=Math.acos(v0.v1/|v0||v1|);
如果两个向量都是单位向量,上面的公式可以简化为
θ=Math.acos(v0.v1);
V0.v1=0 =》两个向量互相垂直
V0.v1>0 =》两个向量的夹角小于90度
V0.v1<0 =》两个向量的夹角大于90度

程序实现:D3DXINLINE FLOAT D3DXVec3Dot ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ){#ifdefD3DX_DEBUGif(!pV1 || !pV2) return 0.0f;#endif returnpV1->x*pV2->x+pV1->y * pV2->y+pV1->z*pV2->z;}

 

叉积(cross product):也称向量积

叉积的结果是一个向量,该向量垂直于相乘的两个向量。

公式:yyyy_html_1b72d65e

注意:叉积不满足交换律,反过来相乘得到的向量与原向量方向相反。
左手坐标系可以通过左手法则来确定叉积返回的向量的方向,从第一个向量向第二个向量弯曲左手,这是拇指所指的方向就是求得的向量的方向。右手坐标系同样的,可以通过右手法则来确定叉积返回的向量的方向,从第一个向量向第二个向量弯曲右手,这是拇指所指的方向就是求得的向量的方向。因此,事实上叉积获得的向量总是垂直于原来两个向量所在的平面。
如果两个向量方向相同或相反,叉积结果将是一个零向量。(即a//b)
叉乘的一个重要应用就是求三角形的法向量。

 

向量函数研究:

 

mul函数

 

self *= a;

如:self={1,2,3,1}    a={2,3,2,1}

则self.mul(a)={2,6,6,1}

即向量self在XYZ轴上分别被放大了2,3,2倍。

 

div函数

self/=a

如:self={1,2,3,1} a={2,3,2,1}

则self.div(a)={0.5,0.66,0.75,0}

即向量slef在XYZ轴上分别被缩小了2,3,2倍。

 

setAdd函数

self = a+b

如:self={0,0,0,0} a={2,3,4,1} b={3,4,5,1}

则slef.setadd(a,b)={5,7,9,2}

即无论自身是否定义,现在等于两点位置之和。

 

四元数类型

四元数实际上还是一个向量,但主要用于旋转。

实体上任何一个点的位置变换都可以看做:位置点Vector

而实体上所有点的位置除了与重心位置向量有关外,还与旋转量Quaternion有关。

Quaternion或Rotation类型的向量由4个分量构成,前三个XYZ并不代表实际的旋转轴向,而是虚数,最后一个也不代表旋转弧度,而是运算的结果.

四元数{W,X,Y,Z}的定义为:
w=cos(rotx/2)*cos(roty/2)*cos(rotz/2)+sin(rotx/2)*sin(roty/2)*sin(rotz/2);
x=sin(rotx/2)*cos(roty/2)*cos(rotz/2)-cos(rotx/2)*sin(roty/2)*sin(rotz/2);
y=cos(rotx/2)*sin(roty/2)*cos(rotz/2)+sin(rotx/2)*cos(roty/2)*sin(rotz/2);
z=cos(rotx/2)*cos(roty/2)*sin(rotz/2)-sin(rotx/2)*sin(roty/2)*cos(rotz/2);

 

W X Y Z 描述
1 0 0 0 恒定四元数,不旋转
0 1 0 0 绕X轴旋转180度
0 0 1 0 绕Y轴旋转180度
0 0 0 1 绕Z轴旋转180度
sqrt(0.5) sqrt(0.5) 0 0 绕X轴旋转90度
sqrt(0.5) 0 sqrt(0.5) 0 绕Y轴旋转90度
sqrt(0.5) 0 0 sqrt(0.5) 绕Z轴旋转90度
sqrt(0.5) -sqrt(0.5) 0 0 绕X轴旋转-90度
sqrt(0.5) 0 -sqrt(0.5) 0 绕Y轴旋转-90度
sqrt(0.5) 0 0 -sqrt(0.5) 绕Z轴旋转-90度

 通过旋转轴和绕该轴旋转的角度可以构造一个四元数
q=[w,x,y,z]
w=cos(a/2)
x=sin(a/2)cos(bx)
y=sin(a/2)cos(by)
z=sin(a/2)cos(bz)
 其中a是绕旋转轴旋转的角度,bx,by,bz为旋转轴在x,y,z方向的分量

 

向量函数研究:

 

Set函数

含义为:this = (x,y,z,r)或this=(vetctor4(x,y,z),r)

范例:q2.set(3,4,5,0.7);

几何意义:指定旋转轴与旋转数值

 

SetInverse函数

含义为:this = q^-1

范例:q2.setInverse(q1);

几何意义:得到与原旋转完全相反的旋转。

 

SetIdentity函数

含义为:this=(0,0,0,1)

q2.setIdentity();

几何意义:完全保持最初的角度,不做任何旋转。

 

SetMul函数

含义为:1、setmul(real r,q1)一个实数乘以一个四元量  2、setmul(q1,q2)两个四元量时,则表示先旋转Q1的角度,再旋转Q2的角度。

范例:q3.setMul((q1(0,1,0,0.2),q2(1,0,0,0.3));

意思就是q3角度是让物体先以Y轴为旋转轴旋转0.2弧度,然后再以X轴为旋转轴旋转0.3个弧度。

 

 

 

 

 

你可能感兴趣的:(K_Math)