向量

0.1. 向量的类型

引擎的向量类有以下三个:

XVECTOR2 表示一个2D向量,成员变量为 x,y

XVECTOR3 表示一个3D向量,成员变量为 x,y,z

XVECTOR4 表示一个4D向量,成员变量为 x,y,z,w

构造方式以XVECTOR3为例:

local v3 = XVECTOR3(1, 2, 3)

print("v3.x: ", v3.x)
print("v3.y: ", v3.y)
print("v3.z: ", v3.z)

输出:

v3.x: 1
v3.y: 2
v3.z: 3

1. 向量的意义

向量是一个有大小和方向的有向线段,一般用于表示距离和方向。

例如一个3D向量 XVECTOR3(5, 0, 0)表示从坐标(0, 0, 0)到坐标(5, 0, 0)的一个方向和距离:方向为坐标轴中X轴的正方向,距离为5。

这样,向量就可以用来表达一个角色的运动情况,比如位置在(1, 0, 0)的小明要移动到(0, 0, 5)的位置,那么他要移动的距离和方向就可以用向量a(-1, 0, 5)来表示:

XVECTOR3 a = XVECTOR3(0, 0, 5) - XVECTOR3(1, 0, 0);

一个向量用于表示距离和方向,那么就会有只想获得向量所表示的方向数据或者只获得向量所表示的距离数据。

获取距离数据叫做向量的取模长,模长的计算很好理解,一个2D向量XVECTOR2(3, 4)的模长就是5,很简单的勾股定理。

向量a的模长用$$|\vec{a}|$$表示。

引擎使用一个float变量表示向量的长度,引擎中提供获取向量模长的函数:

local v2 = XVECTOR2(3, 4)
local fLength = v2:Magnitude()

local v3 = XVECTOR3(1, 1, 1)
local fLength = v3:Magnitude()

获取方向数据的方式就是清除掉向量中的距离数据,我们把距离为1的向量称为单位向量。单位向量只表示一个方向。例如XVECTOR3(0, 1, 0)表示Y轴向上方向。

引擎提供了清楚距离数据的函数,归一化函数,调用函数后的向量会变成单位向量,为了方便具体业务的时候,该函数还会返回归一化之前的向量模长:

local v3 = XVECTOR3(5, 0, 0)
local fLength = v3:Normalize()

print("fLength: ", fLength)
print("v3: ", v3.x, v3.y, v3.z)

输出:

"fLength: 5"
"v3: 1 0 0"

2. 向量的运算

向量和数值之间支持乘除法的运算,向量之间支持加减乘的运算:

2.1. 向量乘数值

向量乘以数值之后,向量所表示的方向不会变,所表示的距离会放大到乘以的数值的倍数:

local v3 = XVECTOR3(1, 2, 2)

print("v3: ", v3.x, v3.y, v3.z)
print("old length:" , v3:Magnitude())

v3 = v3 * 2

print("v3: ", v3.x, v3.y, v3.z)
print("new length:" , v3:Magnitude())

输出:

"v3: 1 2 2"
"old length: 3"
"v3: 2 4 4"
"new length: 6"

2.2. 向量除以数值

即是向量乘以数值的反运算。

2.3. 向量加向量

local a = XVECTOR3(5, 6, 7)
local b = XVECTOR3(1, 1, 1)

local c = a + b

print("c: ", c.x, c.y, c.z)

输出:

"c: 6 7 8"

2.4. 向量减向量

local a = XVECTOR3(5, 6, 7)
local b = XVECTOR3(1, 1, 1)

local c = a - b

print("c: ", c.x, c.y, c.z)

输出:

"c: 4 5 6"

2.5. 向量乘向量

向量乘向量分为点乘叉乘

2.5.1. 向量点乘

向量点乘向量的结果是一个float类型的浮点数。

向量a 和 向量 b 的点乘结果有两种计算方式,计算结果是一样的:

  1. $$ \vec {a} \cdot \vec {b} = cos \theta \ast |\vec {a}| \ast |\vec {b}| $$

  2. $$ {\vec {a}} \cdot {\vec {b}} = a.x \ast b.x + a.y \ast b.y + a.z \ast b.z $$

由公式1我们可以知道,通过向量点乘,我们能获取两个向量的夹角的大小。

因为cos函数的特殊性,我们还可以判断两个向量是否同向:

  1. 如果a与b点乘的结果大于0,表示a与b之间的夹角在0到90度之间,a与b在同一方向

  2. 如果a与b点乘的结果等于0,表示a与b之间的夹角为90度,a与b垂直

  3. 如果a与b点乘的结果小于0,表示a与b之间的夹角在90到180度之间,a与b在相反方向

我们可以通过引擎提供的函数获取两个向量的点乘结果:

local a = XVECTOR3(1, 0, 0)
local b = XVECTOR3(0, 1, 0)

local fValue = DotProduct(a, b)

print("fValue: ", fValue)

输出:

fValue: 0

2.5.2. 向量叉乘

向量叉乘会比较复杂,两个向量叉乘的结果是一个新向量。

对于两个3D向量来说,两个向量叉乘的结果是一个垂直于这两个向量的新向量。

对于叉乘的应用,比较多的是求一个平面的法向量(垂直于平面的向量):

在3D空间中,三个不重叠的点可以固定一个平面,我们可以使用这三个点构造两个向量进行叉乘,来获得同时垂直于这两个向量的新向量,这个新向量也就垂直于这个平面。

对于两个2D向量来说,不存在两个2D向量的垂直向量。乍一看2D向量的叉乘没有意义。实际上两个2D向量叉乘出了一个新向量,这个新向量的模长,是这两个向量所组成的三角形的面积。

引擎提供了两个向量的叉乘函数,使用效果如下:

local a = XVECTOR3(1, 0, 0)
local b = XVECTOR3(0, 1, 0)

local c = CrossProduct(a, b)

print("c: ", c.x, c.y, c.z)

输出:

c: 0, 0, 1 
@Copyright © cosmos 2019 all right reserved,powered by Gitbook修订时间: 2021-04-12 18:28:17

results matching ""

    No results matching ""