向量(Vector),又称矢量,可以用来表达同时具有大小和方向的物理量。
向量没有位置,只有方向(Direction)和大小(Magnitude,也叫做模或长度)。这听起来不可思议,但其实日常生活中很多量有大小(Size)和方向(Direction),却没有位置(Position)。例如:
位移:“向前走三步”。这句话好像是关于位置的,但其实句子中使用的量表示的是相对位移,而不是绝对位置。这个相对位移由大小(三步)和方向(向前)构成,所以位移是向量。
速度:“我们以50公里每小时的速度向北行驶”。这句话描述了一个量,它有大小(50公里每小时)和方向(北),但没有具体位置,所以速度也是向量。
在几何学上,我们用带箭头的有向线段来表示向量。箭头一端叫Head(头),另外一端叫Tail(尾)。

向量可以为任意维度(Dimension),向量中的数表达了向量在每个维度上的有向位移。标量(Scalar)可认为是一个1维向量。在游戏中通常只使用2维、3维和4维向量。
下图2维向量¯v和¯w尽管起始点不同,但它们的方向和大小是相同的,因此,¯v和¯w是相等的向量。

数学中在字母上面加一横来表示向量,如¯v。
水平书写的叫行向量:
¯v=(x,y,z)
垂直书写的叫列向量:
¯v=(x,y,z)T=⎛⎜⎝xyz⎞⎟⎠
点与向量的关系
点描述位置,向量描述位移,在概念上完全不同。思考位置时,想象一个点,思考位移时,想象一个向量和一个箭头。
向量平移至尾部与所在坐标系原点恰好重合的位置时,向量位于标准位置(standard position)。
一旦向量处于标准位置,就可以用该点的位置坐标来表示该向量。从这个层面上看,点和向量在数学上又是等价的。

向量相等
在几何学中,如果两个向量的长度和方向都相同,那么这两个向量相等。
在代数学中,两个向量相等,当且仅当它们对应各分量都相等。即:vx=wx,vy=wy,vz=wz,则¯v=¯w
在计算机中,判断两个向量是否相等,会使用代数学方法来实现。由于float的不精确性,判断两个float值是否相等,会使用两者差值的绝对值是否小于EPSILON=0.001f阈值(tolerance)来判定。
∣vi−wi∣<EPSION
向量数乘、向量加减法统称为向量的线性运算。
向量数乘
标量可以与向量相乘,来对向量进行缩放。该运算不改变向量的方向,除非该向量与负数相乘,这时向量的方向与原来的方向相反。
原向量和数乘后的向量之间的夹角为0,是平行的,又称共线。

公式如下:
k⋅¯v=⎛⎜⎝k⋅vxk⋅vyk⋅vz⎞⎟⎠
向量取反
对一个向量取反(Negate)会将其方向逆转。一个指向东北的向量取反后就指向西南方向了。我们在一个向量的每个分量前加负号就可以实现取反了(或者说用-1数乘该向量):
−¯v=−⎛⎜⎝vxvyvz⎞⎟⎠=⎛⎜⎝−vx−vy−vz⎞⎟⎠
定理1:设向量¯v≠0,那么,向量¯w平行于¯v的充分必要条件是:存在唯一的实数k,使¯w=k⋅¯v。
向量数乘的性质
(1) 交换律
k⋅¯v=¯v⋅k
(2) 结合率
k1⋅(k2⋅¯v)=(k1⋅k2)⋅¯v
(3) 分配律
k⋅(¯v+¯w)=k⋅¯v+k⋅¯w
(k1+k2)⋅¯v=k1⋅¯v+k2⋅¯v
向量加法
向量的加法可以被定义为是分量的(Component-wise)相加,即将一个向量中的每一个分量加上另一个向量的对应分量:
¯v+¯w=⎛⎜⎝vx+wxvy+wyvz+wz⎞⎟⎠
示例如下:
¯v=⎛⎜⎝123⎞⎟⎠,¯w=⎛⎜⎝456⎞⎟⎠→¯v+¯w=⎛⎜⎝1+42+53+6⎞⎟⎠=⎛⎜⎝579⎞⎟⎠
用平行四边形法则(Parallelogram law),向量¯v =(4, 2)和¯w =(1, 2)可以直观地表示为:

几何意义:把¯w进行平移,使¯v的尾部与¯w的头部重合。¯v+¯w为:以¯v的尾部为起点、以平移后的¯w的头部为终点所作的向量。
向量的加法运算与物理学中不同作用力合成合力的规则是一致的。如果两个力(两个向量)作用的方向越一致,形成的合力也越大。
三个向量¯u、¯v、¯w相加的情况如下:

向量加法的性质
(1) 交换律
¯v+¯w=¯w+¯v
(2) 结合律
¯u+(¯v+¯w)=(¯u+¯v)+¯w
向量减法
向量的减法等于加上第二个向量的相反向量:
¯w−¯v=⎛⎜⎝wx−vxwy−vywz−vz⎞⎟⎠
示例如下:
¯w=⎛⎜⎝123⎞⎟⎠,¯v=⎛⎜⎝456⎞⎟⎠→¯w+−¯v=⎛⎜⎝1+(−4)2+(−5)3+(−6)⎞⎟⎠=⎛⎜⎝−3−3−3⎞⎟⎠
两个向量的相减会得到这两个向量指向位置的差。如下图,也是符合平行四边形法则的。

¯w和¯v的差为:以¯v指向¯w的向量。该向量的模为点(vx, vy)到点(wx, wy)的距离。
向量的模(也称长度或大小)
向量的模的几何意义是有向线段的长度。
我们使用勾股定理(Pythagoras Theorem)来获取向量的长度(Length)/大小(Magnitude)。如果把向量的x与y分量画出来,该向量会和x与y分量为边形成一个三角形。

因为两条边(x和y)是已知的,则可以通过勾股定理来计算斜边¯v的长度:
||¯v||=√x2+y2
例子中向量(4, 2)的长度等于:
||¯v||=√42+22=√16+4=√20=4.47
将这个公式拓展到三维空间为:
||¯v||=√x2+y2+z2
向量的模的性质
(1) 数乘向量的模等于系数绝对值乘以该向量的模
||k⋅¯v||=|k|⋅||¯v||
(2) 向量的大小非负
||¯v||≥0
(3) 两边之和大于等于第三边
||¯w||+||¯v||≥||¯w+¯v||
||¯w||+||¯v||≥||¯w−¯v||
(4) 两边之差小于等于第三边
||¯w||−||¯v||≤||¯w−¯v||
||¯w||−||¯v||≤||¯w+¯v||
向量的方向角
非零向量¯v与三条坐标轴的夹角α、β、γ称为向量¯v的方向角。
cosα、cosβ、cosγ称为向量¯v的方向余弦。

从几何上可知:
cosα=vx||¯v||
cosβ=vy||¯v||
cosγ=vy||¯v||
进一步推导可得:
cos2α+cos2β+cos2γ=v2x+v2y+v2z||¯v||2=1
零向量
零向量(Zero Vector)的所有分量都是0。
零向量是唯一模为0的向量,也是唯一一个没有方向的向量。
单位向量
单位向量(Unit Vector)有一个特别的性质,即:它的长度是1。
很多时候,我们只关心向量的方向,而不关心其大小。如:我面向的是什么方向?这种情况下,使用单位向量将非常方便。
我们可以用任意向量的每个分量除以向量的长度得到它的单位向量^n,如下:
^n=¯v||¯v||=⎛⎜
⎜
⎜
⎜⎝vx||¯v||vy||¯v||vz||¯v||⎞⎟
⎟
⎟
⎟⎠
我们把这种方法叫做一个向量的标准化(Normalizing,或称规范化)。单位向量头上有一个^样子的记号。通常单位向量会变得很有用,特别是在只关心方向不关心长度的时候(如果改变向量的长度,它的方向并不会改变)。

向量点乘
点乘,即点积(dot product);又称内积;又称标量积(scalar product)。
点乘是通过将对应分量逐个相乘,然后再把所得积相加来计算的。
¯v⋅¯w=vx⋅wx+vy⋅wy+vz⋅wz
示例如下:
⎛⎜⎝0.6−0.80⎞⎟⎠⋅⎛⎜⎝010⎞⎟⎠=(0.6∗0)+(−0.8∗1)+(0∗0)=−0.8
根据向量减法,AB线段长度为||¯v−¯w||,而OA线段长度为||¯v||,OB线段长度为||¯w||。如下图所示:

从余弦定理,可得到如下关系:
cosθ=||¯v||2+||¯w||2−(||¯v−¯w||)22⋅||¯v||⋅||¯w||=vx2+vy2+wx2+wy2−((vx−wx)2+(vy−wy)2)2⋅||¯v||⋅||¯w||=vx⋅wx+vy⋅wy||¯v||⋅||¯w||
因此,可推导得到:
vx⋅wx+vy⋅wy=||¯v||⋅||¯w||⋅cosθ
即两个向量的点乘等于它们的数乘结果乘以两个向量之间夹角的余弦值:
¯v⋅¯w=||¯v||⋅||¯w||⋅cosθ
它们之间的夹角(^¯v,¯w)或(^¯w,¯v)为θ,其范围为[0, π]。
在物理学中,一个力¯F对物体所作的功W为:(力¯F的大小)⋅(物体位移¯s的大小)⋅(力¯F与位移¯s方向夹角的余弦值)
W=||¯F||⋅||¯s||⋅cos(^¯F,¯s)
也就是说,所作的功W为力F和位移s的点乘,即:W=¯F⋅¯s

如果v和w都是单位向量,这个公式会简化成:
¯v⋅¯w=1⋅1⋅cosθ=cosθ
当向量点乘自己时,得到如下关系式:
¯v⋅¯v=vx⋅vx+vy⋅vy+vz⋅vz=v2x+v2y+v2z=||¯v||2
可以通过点乘的结果计算两个非单位向量的夹角,点乘的结果除以两个向量的长度之积,得到的结果就是夹角的余弦值(cosθ):
cosθ=¯v⋅¯w||¯v||⋅||¯w||
向量点乘的性质
(1) 交换律
¯v⋅¯w=¯w⋅¯v
定理:
(1) ¯v⋅¯w = 0,则夹角(^¯v,¯w)为直角,即¯v⊥¯w(两向量正交)
相反,如果夹角(^¯v,¯w)为直角,即¯v⊥¯w(两向量正交),则¯v⋅¯w = 0
(2) ¯v⋅¯w > 0,则夹角(^¯v,¯w)为锐角,小于90∘
相反,如果夹角(^¯v,¯w)为锐角,小于90∘,则 ¯v⋅¯w > 0
(3) ¯v⋅¯w < 0,则夹角(^¯v,¯w)为钝角,大于90∘
相反,如果夹角(^¯v,¯w)为钝角,大于90∘,则¯v⋅¯w < 0
向量的正交投影
向量¯w在向量¯u上的正交投影(orthogonal projection)向量¯p,记作:proj¯u(¯w)

存在一个标量k,使得:
¯p=k⋅^u=k⋅¯u||¯u||
根据三角函数,k=cosθ⋅||¯w||
因此,可以得到:
¯p=k⋅^u=k⋅¯u||¯u||=cosθ⋅||¯w||⋅¯u||¯u||=cosθ⋅||¯w||⋅||¯u||⋅¯u||¯u||2=(¯w⋅¯u)⋅¯u||¯u||2
使用正交投影进行规范正交化处理
如果向量集{¯v0,¯v1,...,¯vn−1}中的每个向量都相互正交(集合内的任一向量都与集合中的其他所有向量正交),且都被单位化,那么这个集合是规范正交(Orthonormal)的。
受数值精度误差累计的影响,会导致规范正交集成为非规范正交集,下面使用正交投影的方法再次对其进行规范正交化处理。
2D情况
对于向量集合{¯v0,¯v1},想将其正交化为{¯w0,¯w1}。
首先假设¯w0=¯v0,然后通过¯v1减去它在¯w0上的分量(投影)来令它正交于¯w0,得到:
¯w1=¯v1−proj¯w0(¯v1)=¯v1−(¯v1⋅¯v0)⋅¯v0||¯v0||2

最后对正交集{¯w0,¯w1}进行规范化即可,得到规范正交集:
{¯w0||¯w0||,¯w1||¯w1||}
3D情况
与2D的处理方法相似,只是步骤更多。
对于向量集合{¯v0,¯v1,¯v2},想将其正交化为{¯w0,¯w1,¯w2}。
首先假设¯w0=¯v0,然后通过¯v1减去它在¯w0上的分量(投影)来令它正交于¯w0,得到:
¯w1=¯v1−proj¯w0(¯v1)=¯v1−(¯v1⋅¯v0)⋅¯v0||¯v0||2
接下来,通过令¯v2依次减去它在¯w0方向的分量(投影)和它在¯w1方向上的分量(投影),使之同时正交于¯w0、¯w1,得到:
¯w2=¯v2−proj¯w0(¯v2)−proj¯w1(¯v2)=¯v2−(¯v2⋅¯v0)⋅¯v0||¯v0||2−(¯v2⋅¯v1)⋅¯v1||¯v1||2

最后对正交集{¯w0,¯w1,¯w2}进行规范化即可,得到规范正交集:
{¯w0||¯w0||,¯w1||¯w1||,¯w2||¯w2||}
n维情况
对于n维向量集{¯v0,¯v1,...,¯vn−1},为了将其正交化为规范正交集{¯w0,¯w1,...,¯wn−1}
就要使用格拉姆--施密特正交化(Gram-Schmidt Orthonormal)方法,上面的2D和3D是其特例,其公式如下:
① 设¯w0=¯v0
② 对于1≤i≤n−1,令wi=vi−∑i−1j=0proj¯wj(¯vi)
③ 对正交集{¯w0,¯w1,...,¯wn−1}进行规范化即可,得到规范正交集:
{¯w0||¯w0||,¯w1||¯w1||,...,¯wn−1||¯wn−1||}
更多格拉姆--施密特正交化(Gram-Schmidt Orthonormal)参看:
如何通俗地理解施密特正交化(bilibili)
如何理解施密特正交化?
施密特正交化
施密特正交化的问题
施密特正交化是有偏差的,取决于基向量的列出的顺序,一个明显的例子是,¯w0=¯v0,总是不变。
下列算法的一个改进是不在一次正交化过程中将整个矩阵完全正交化,而是选择一个小的因子k,每次只减去投影的k倍,而不是一次将投影全部减去。
还体现在最初的轴上减去投影,避免了因为运算顺序不同带来的误差。以3维为例,算法如下:
¯w0=¯v0−k⋅(¯v0⋅¯v1)⋅¯v1||¯v1||2−k⋅(¯v0⋅¯v2)⋅¯v2||¯v2||2
¯w1=¯v1−k⋅(¯v1⋅¯v0)⋅¯v0||¯v0||2−k⋅(¯v1⋅¯v2)⋅¯v2||¯v2||2
¯w2=¯v2−k⋅(¯v2⋅¯v0)⋅¯v0||¯v0||2−k⋅(¯v2⋅¯v1)⋅¯v1||¯v1||2
该算法的每次迭代都会使这些基向量比原来的基向量更为正交化,但可能不是完全正交化的,多次重复这个过程,最终将得到一组正交基。
要得到完美的结果,就得选择一个适当的因子k并迭代足够多次(如10次)。最后,进行标准化,最后就会得到一组标准的正交基。
向量叉乘
叉乘,即叉积(cross product);又称外积;又称向量积。
叉乘只在3D空间中才有定义,它需要两个不平行向量作为输入,生成一个正交于两个输入向量的第三个向量。如果输入的两个向量也是正交的,那么叉乘之后将会产生3个互相正交的向量。
按照右手定则,从向量¯v 出发,再以0≤θ≤π的角度弯曲四指,指向向量¯w,最后伸直拇指的方向为叉乘向量¯vׯw所在的方向。

注1:数学中使用的是右手定则(即:右手坐标系)
注2:D3D使用的是左手定则,OpenGL使用的是右手定则
向量¯v和向量¯w的叉乘公式如下:
⎛⎜⎝vxvyvz⎞⎟⎠×⎛⎜⎝wxwywz⎞⎟⎠=⎛⎜⎝vy⋅wz−vz⋅wyvz⋅wx−vx⋅wzvx⋅wy−vy⋅wx⎞⎟⎠
||¯vׯw||=√(vy⋅wz−vz⋅wy)2+(vz⋅wx−vx⋅wz)2+(vx⋅wy−vy⋅wx)2
=√(v2y⋅w2z+v2z⋅w2y+v2z⋅w2x+v2x⋅w2z+v2x⋅w2y+v2y⋅w2x)−(2⋅vy⋅wy⋅vz⋅wz+2⋅vz⋅wz⋅vx⋅wx+2⋅vx⋅wx⋅vy⋅wy)
=√(v2y⋅w2z+v2z⋅w2y+v2z⋅w2x+v2x⋅w2z+v2x⋅w2y+v2y⋅w2x+(v2x⋅w2x+v2y⋅w2y+v2z⋅w2z))−((v2x⋅w2x+v2y⋅w2y+v2z⋅w2z)+2⋅vy⋅wy⋅vz⋅wz+2⋅vz⋅wz⋅vx⋅wx+2⋅vx⋅wx⋅vy⋅wy)
=√(v2y⋅w2z+v2z⋅w2y+v2z⋅w2x+v2x⋅w2z+v2x⋅w2y+v2y⋅w2x+v2x⋅w2x+v2y⋅w2y+v2z⋅w2z)−((vx⋅wx)2+(vy⋅wy)2+(vz⋅wz)2+2⋅(vy⋅wy)⋅(vz⋅wz)+2⋅(vz⋅wz)⋅(vx⋅wx)+2⋅(vx⋅wx)⋅(vy⋅wy))
=√(v2x+v2y+v2z)⋅(w2x+w2y+w2z)−(vx⋅wx+vy⋅wy+vz⋅wz)2
=√||¯v||2⋅||¯w||2−||¯v⋅¯w||2
=√||¯v||2⋅||¯w||2−(||¯v||⋅||¯w||⋅cosθ)2
=√||¯v||2⋅||¯w||2−||¯v||2⋅||¯w||2⋅cos2θ
=||¯v||⋅||¯w||⋅√1−cos2θ
=||¯v||⋅||¯w||⋅sinθ
注:它们之间的夹角(^¯v,¯w)或(^¯w,¯v)为θ,其范围为[0, π]。
从几何上,||¯vׯw||为由向量¯v和向量¯w构成平行四边形的面积。

在物理学中,在研究物体转动问题时,不但要考虑这物体所受的力,还要分析这些力所产生的力矩。
设O为一根杠杆L的支点,力¯F作用于这杠杆的P点处,¯F与¯OP的夹角为θ,则力¯F对支点O的力矩是一个向量¯M,它的模为:
||¯M||=||¯F||⋅OQ=||¯F||⋅||¯OP||⋅sinθ=||¯FׯOP||

向量叉乘的性质
(1) 任意向量与自身的叉乘等于零向量
¯vׯv=¯0
(2) 叉乘逆交换律
¯vׯw=−(¯wׯv)
(3) 叉乘的操作数同时变负得到相同的结果
¯vׯw=(−¯v)×(−¯w)
(4) 数乘对叉乘的结合律
k⋅(¯vׯw)=(k⋅¯v)ׯw=¯v×(k⋅¯w)
(5) 叉乘对向量加法的分配律
¯u×(¯v+¯w)=¯uׯv+¯uׯw
(6) 向量与另一个向量的叉乘再点乘该向量等于0
¯v⋅(¯vׯw)=0
定理1:向量¯v与向量¯w平行的充分必要条件是¯vׯw=¯0
通过叉乘进行规范正交化处理
在计算机图形学中,会使用3个规范正交向量{¯v0,¯v1,¯v2}来表示摄像机的空间姿态,但受数值精度误差累计的影响,会导致其成为非规范正交集。
其中第三个向量¯v2描述的是摄像机的观察方向。在对这些向量进行正交化处理过程中,我们通常不希望改变此摄像机的观察方向。可以使用叉乘进行正交化处理,得到新的规范正交集:
{¯w0,¯w1,¯w2}
其中:
¯w2=¯v2||¯v2||
¯w1=¯w2ׯv0||¯w2ׯv0||
¯w0=¯w1ׯw2
计算2维向量的正交向量
用复数逆时针旋转90度来计算
(x+y⋅i)⋅(cosπ2+sinπ2⋅i)=(x+y⋅i)⋅(i)=−y+x⋅i
因此,向量¯v(x,y)的正交向量为¯w(−y,x)。

不难看出,向量¯w′(y,−x)也与向量¯v(x,y)正交。
向量混合积
对于三个向量¯u、¯v和¯w,如果先做两向量¯u和¯v的向量积¯uׯv,把所得到的向量与第三个向量¯w再作数量积(¯uׯv)⋅¯w
这样得到的数量叫做三向量¯u、¯v和¯w的混合积,记作[¯u¯v¯w]。
(¯uׯv)⋅¯w=||¯uׯv||⋅||¯w||⋅cosα=(||¯u||⋅||¯v||⋅cosβ)⋅(||¯w||⋅cosα)=S平行四边形⋅h高=V平行六面体
从几何学上,三个向量¯u、¯v和¯w的混合积为它们构成的平行六面体的体积。

定理1:三个向量¯u、¯v和¯w共面的充分必要条件是它们的混合积(¯uׯv)⋅¯w=0
参考
变换(LearnOpenGL CN)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2019-07-17 python前后台tcp/udp通讯示例