游戏开发中的数学基础

 

源自《3D游戏编程大师技巧(上册)》的总结

 

表示物体的相对位置信息(相对原点),主要分为以下几种:

2D坐标系:

2D 笛卡尔坐标系。主要运用 有序数对 来表示点的位置信息
2D 极坐标:方向和距离来定义点
笛卡尔和极坐标之间的转换。

极坐标 to 笛卡尔
  x = rcos(θ)
  y = rsin(θ)
  笛卡尔 to 极坐标
  r = sqrt(x^2+y^2)
  θ = arctan(y/x)=tan^-1(y/x)  —— tan的反三角函数
  warming:当x=0时,正切为无穷大!!!若x=0,则θ=90

3D坐标系(3D游戏的重点)

3D笛卡尔坐标系

三条轴(有三个相互正交的向量组成)、八个卦限、三个平面(两两组成)
依据新增的Z轴方向的不同,分为 左手坐标系 (LHS)和 右手坐标系 (RHS)。

DirectX使用左手坐标系,OpenGL使用的是右手坐标系

3D柱面坐标(三维的极坐标)

只是在二维极坐标上加了一个描述高度的变量(Z轴)
点的表示:(r,θ,h)

三维笛卡尔和柱面坐标的相互转换

极坐标 to 笛卡尔
  x = rcos(θ)
  y = rsin(θ)
  z = z;
  笛卡尔 to 极坐标
  r = sqrt(x^2+y^2)
  θ = arctan(y/x)=tan^-1(y/x)  —— tan的反三角函数
  z = z;
  warming:x=0时与二维转换的类似,不再复述

3D球面坐标。表示点P的坐标为(ρ,Ф,θ),其中:

ρ: 点P到原点的距离
Ф:原点到点P的线段OP与正Z轴之间的夹角
θ:OP在x-y平面上的投影与正x轴之间的夹角

关于球坐标与笛卡尔之间的转换。请自己画图推导加深印象,这里不再给出

小结 :关于坐标轴,它可以非常具有创造力。你们可以根据自己的需求,利用数学几何知识进行构建,以达到更好的计算效率。但上述给出的坐标系已经足够大部分情况的使用。

直角三角形

弧度制:整个圆周为360°, 在弧度制中为2Π 。计算机函数sin()和cos()的参数以弧度为单位,而不是以度为单位!

 

弧度与度之间的关系

以度为单位的角度 以弧度为单位的角度 以度为单位的角度 以弧度为单位的角度
360度 2*PI(大约6.28弧度) 57.296度 1弧度
180度 PI弧度(大约3.1159弧度) 1.0度 0.0175弧度

 

三角形三个内角为180度(PI弧度)

 

角的对边和邻边、直角三角形的斜边

 

勾股定理

 

三角函数:sin(θ)、cos(θ)、tan(θ)

反三角函数:三角函数的反函数sin -1 (θ)、cos -1 (θ)、tan -1 (θ)
三角恒等式:

倒数函数:csc(θ)=1/sin(θ) | sec(θ)=1/cos(θ) |cot(θ)=1/tan(θ)
三角函数的勾股定理:sin 2 (θ) + cos 2 (θ)=1
转换恒等式:sin(θ) = cos(θ-PI/2)
反射恒等式:sin(-θ) = -sin(θ) | cos(-θ)=cos(θ)
角度相加恒等式:sin(θ 1 + θ 2 )=sin(θ 1 )*cos(θ 1 ) + sin(θ 2 )*cos(θ 2 )等(高中知识)

2/3D向量表示一条 有向的线段

向量的一些说明:

向量在定义之后其实都可以相对原点来表示的。任何向量都可以用以(0,0)或(0,0,0)作为起点。
向量的重要属性有:长度和方向
向量实质上是一个有序数集

向量长度:也称向量的模。| u |=sqrt(x 2 +y 2 )
归一化(normalize):转化为 单位向量 ,数集各值除以模即可
向量的计算

数乘:向量模的伸缩、改向(乘上负数)
加、减、
点积

U 和 V之间的夹角为90°,则点积为0
U 和 V之间的夹角小于90°,点积大于0
U 和 V之间的夹角大于90°,点积小于0
U 和 V相等,点积为|U| 2 , |V| 2

投影计算

叉积

·点积
    U*V = ux*vx + uy*vy = |U|*|V|*cos(θ);
    
·叉积
          |i  j  k |
   U×V  = |ux uy uz|
          |vx vy vz|

用线性组合表示向量:n=x i +y j +z k

矩阵与线性代数

 

为了更改习惯。在计算机中,矩阵中元素的下标从0开始。

基本的矩阵概念(引出等)参考《线性代数》教材
基本矩阵

单位矩阵:主对角线的所有元素为1,其余元素为0的方阵。单位矩阵的性质: A * I = I * A = A (I和A必须有相同的维数)
零矩阵:所有元素均为0.

矩阵加法、矩阵的转置
矩阵乘法:数乘和矩阵相乘

数乘:k作为乘数,对矩阵中每一个元素都乘上k
矩阵相乘:限制要求为前一个矩阵的 列 要等于后一个矩阵的 行

矩阵运算满足的定律

加法交换律
加法结合律
乘法结合律
分配率(注意:乘法与括号中的矩阵在分配后的顺序一定要保持一致)
单位矩阵的乘法属性: A * I = I * A = A

逆矩阵与方程组求解

逆矩阵的求法
克莱姆法则
使用矩阵进行变换:M’=M * M1 * M2 * M3 (M1、M2、M3为变换矩阵)
齐次坐标:n维坐标的齐次坐标为n+1维,多出来的维度w意义在于 统一变换矩阵计算 ,常规坐标需要各坐标量除以w
应用矩阵变换

平移矩阵(引擎底层的计算)

|1  0  0  0|
[x',y',z',1]=[x,y,z,1]*|0  1  0  0|
                       |0  0  1  0|
                       |Tx Ty Tz 1|
                       
逆矩阵为:
                       | 1   0   0  0|
[x',y',z',1]=[x,y,z,1]*| 0   1   0  0|
                       | 0   0   1  0|
                       |-Tx -Ty -Tz 1|

矩阵缩放(引擎底层的计算)

|Sx 0  0  0|
[x',y',z',1]=[x,y,z,1]*|1  Sy 0  0|
                       |0  1  Sz 0|
                       |0  0  0  1|
                       
逆矩阵为:
                       |1/Sx 0  0  0|
[x',y',z',1]=[x,y,z,1]*|1  1/Sy 0  0|
                       |0  1  1/Sz 0|
                       |0  0    0  1|

矩阵旋转(引擎底层的计算)

1、绕x轴旋转
                       |1   0    0    0|
[x',y',z',1]=[x,y,z,1]*|1 cosx  sinx  0|
                       |0 -sinx cosx  0|
                       |0   0    0    1|
2、绕y轴旋转
                       |cosx 0 -sinx 0|
[x',y',z',1]=[x,y,z,1]*| 0   1   0   0|
                       |sinx 0 cosx  0|
                       | 0   0   0   1|
3、绕z轴旋转
                       |cosx   0   sinx 0|
[x',y',z',1]=[x,y,z,1]*|-sinx cosx  0   0|
                       |  0    0    1   0|
                       |  0    0    0   1|
                       
逆矩阵:将0改为-0

 

基本几何实体

点:坐标表示、齐次坐标
直线:两个点确定一条直线,表示直线的方法如下:

2D直线

斜率-截距形式:y=m*x+b
点斜式:(x-x0) = m*(y-y0)
通用形式:a * x+b * y + c = 0
求两个点的交点(利用逆矩阵)

a1*x + b1*y = c1
a2*x + b2*y = c2
A=| a1 b1 |    X= | x |    B=| c1 |
  | a2 b2 |       | y |      | c2 |
求解:A*X=C 即为:  X=A^-1*B

3D空间中的直线(知识点为于高等数学下册)

参数化的方程 :P(x,y,z)=P0 + ( P0P1 )*t (t为参数, P0P1 为向量)
显示形式:(x-x0)/a = (y-y0)/b = (z-z0)/c,其中 (a,b,c)为 P0P1 的各个分量

平面 (一般指3D空间的平面)

所有的 3D平面都能延伸到无穷远
所有的平面都将整个平面分成两个半空间(这对于各种空间划分算法和碰撞检测非常重要)
平面的确定要素:平面法线向量 n 与平面一定点P0。性质: 平面法线垂直于平面上任一直线,垂直向量点积为0 :可得: PP0 * n =0
几种常见的平面方程:

点法式:a*(x-x0) + b*(y-y0) + c*(z=z0) = 0
一般式:a * x + b * y +c * z + d = 0

求平面交线:联立方程组、求解方程组
点与直线位置的关系:

平面方程:hs= a*(x-x0) + b*(y-y0) + c*(z=z0) 。点P(x,y,z)
将点P带入方程,若:

hs=0 —— 位于平面上
hs>0 —— 位于正半空间
hs<0 —— 位于负半空间

直线与平面的交点

使用参数化方程

 

通过使用参数化方程,可以用 单变量 函数来表示直线或曲线。

2D参数化直线

起始点P0(x0,y0) , 终点P1(x2,y2)
直线方向向量 s =P1-P0 = (x1-x0 , y1-y0)
2D直线方程为:l :stuck_out_tongue:’ = P0+ s *t t∈(0,1)

3D直线参数化类似:P’=P0+ s *t t(0,1) ,其中 s 为 带模 的方向向量
关于直线参数方程的实际应用:

两线段是否有交点(实际问题:两架飞船是否会相撞等)根据交点x、y分别相等建立二元一次方程组,解得两个参数t1、t2,分别判断t1、t2是否在他们各自的定义域,如果都在则有交点。
3D直线与平面的交点:将3D直线化为分别关于x,y,z的参数方程,带入平面求出参数t,判断t是否在定义域内

四元数是抽象的,它不代表现实中的任何东西(因为是关于复数),只在数学意义上存在。

在3D图形学的应用:3D相机控制、压缩存储、平滑3D插值
复数概念:针对特定无意义的值:当对-1开平方时,它本是没有意义的。数学家提出了 复数 的概念

i=sqrt(-1),即:
    i*i=1;
    
    复数的形式: x= a + b*i
                 a —— 实部
                 b —— 虚部
    
    图形可以在复平面表示:一般约定:x轴为实部,y轴为虚部

复数的计算:

数乘、加减、乘法(略)
重点强调除法:

若实部均为0,虚部直接相除即可
若实部均不为0,其技巧在于将分母表量化(利用平方差公式,即乘于 共轭复数 )

共轭复数:实部相等,虚部互为相反数的复数

倒数:即分子为1的除法

复数的范数:将复数表示为向量之后,复数的范数就相当于“向量”的模,即:

z = a + b*i,则:
    范数为:
    |z| = sqrt(a^2 + b^2)
    
    也有:设复数z的共轭复数为z1,则有:
    |z| = sqrt(z * z1)

超复数

四元数就是超复数(hyper-complex number),超复数可以指任何东西,但一般指有多个虚部的复数。
四元数:有 一个实部和三个虚部 的复数

q = q0 + q1*i + q2*j + q3*k
  q0,q1,q2,q3均为实数
   
  特殊的,当i=<1,0,0>  j=<0,1,0> k=<0,0,1>
  他们组成了四元数q的向量基

四元数性质:i 2 = j 2 = k 2 = -1 =i * j * k (最后一项类似于叉积)

四元数的运算

加法、减法
四元数乘法:和传统多项式的乘法算法一致,去括号+各项相乘,但这里给出另外一个公式:

p=p0 + p1*i + p2*j + p3*k = p0*pv
    q=q0 + q1*i + q2*j + q3*k = q0*qv
    
    则:
    r= p*q =(p0*q0 - (pv·qv)) + (p0*qv + q0*pv + pv×qv) = r0 + rv
    
    注:· 为点乘,× 为叉乘

共轭四元数:q * 实部相等,虚部全部互为相反数
四元数的范数:|q|=sqrt(q0 2 + q1 2 + q2 2 + q3 2 ) = sqrt(q * q * )
倒数:(重要)可以用来简化四元数旋转

给定四元数q,我们要找到另外一个四元数q^-1,使得下列等式成立:
    q*q^-1 = 1 =q^-1*q    倒数
    
    · 两边同时乘以共轭复数q1,得
      (q*q^-1)*(q1) = (q^-1*q)*(q1) = q1
    · 乘法结合率
      q^-1*(q*q1) = q1
    · 因为:(q*q1)=|q|^2  (共轭复数相乘等于范数的平方)
      q^-1 = (q1) / (|q|^2)
      
      如果:q是个单位四元数,则|q|^2 = 1,从而:
      q^-1 = q1  (q1为q的共轭复数)

*四元数的应用:3D图形学的旋转和插值(会另起文章专门深入讨论)

发表评论

电子邮件地址不会被公开。 必填项已用*标注