首页 > 代码库 > 《游戏人工智能编程案例精粹》读书笔记—数学和物理学初探

《游戏人工智能编程案例精粹》读书笔记—数学和物理学初探

1.1.1 笛卡尔坐标系

在二维空间中,笛卡尔坐标系被定义成两个坐标轴成直角相交并且用单位长度标出。水平轴称为x 轴,而垂直轴称为y 轴,两个轴的交点称为原点,如图1.1 所示。

QQ截圖20140727232538

如图1.1所示,每个坐标轴端点的箭头表示它们在每个方向上无限延伸。假想有一张无限大的纸,上面有x 轴和y 轴,纸就表示 xy 平面,所有二维的笛卡尔坐标系中的点都可以给制在这个平面上。在2D 空间中的一个点可以用一对坐标(x,y) 表示。x 和y 的值代表沿着各自的轴上的距离。

为了表达三维空间,需要另外一个坐标轴z铀。z 轴从你的屏幕的后面延伸到屏幕的前面,在途中穿过原点。如图1.2 所示。

QQ截圖20140727233637

1.1.2 函数和方程

函数的概念是数学的基础。函数表达了两个(或更多个) 称为变量的项之间的关系,并且典型的写法是方程的形式(一个代数表达式等于另一个代数表达式)。

图1.3的左边显示了函数y=2x 在 xy 平面上绘制出来是怎样的图形,使用的x 值的范围是-5.0-5.0。

1122

 

为了把函数y=mx+c 给制成一个图形,你必须首先有常数m 和c 的一些值。我们设m=2和c=3,给出函数y=2x+3。图1.3 右边显示了结果图形。

y=mx+c 是定义在三维空间的所有直线的函数。常数m定义了直线的斜率,或者说是直线倾斜的陡峭程度,常数c 规定了直线与y 轴相交的位置。

1.1.2.1 指数和幂

一个指数函数定义如下:

213213211111111

α 称为底而x 称为幂。如果口头描述此方程,就是f(x)等于a 的x 次幂。这意味着a 与自身相乘x 次。

图1.5 显示了方程在a=2 时绘制的图形。曲线明显地显示了y 的值是如何随着x 的值快速增加的。这种曲线的类型常常被称为指数增长。

QQ截圖20140728001749

 

1.1.2.3 化简方程

通常,要解一个方程必须先化简。实现化简的一个黄金定律是在方程的两边通过同时加、减、乘或除一些项来得到方程的解。(这个规则有一个例外:当进行乘或除时,该项不能为零。〉只要方程两边做的运算相同,那么两边将保持相等。

1.1.3 三角学

角和弧度

一个角定义为有公共原点的两条射线的分散度,见图1.7。

弧度是以原点为中心的单位半径(半径为1) 圆为基准的一种度量单位。圆的半径是从圆的中心到圆周上的点的距离。在画有两条射线的同一图(见图1.7)中作单位圆,我们得到图1.8。在两条射线之间的曲线段的长度(在图中显示成点线的)是它们的夹角在弧度制下角的度量。

QQ截圖20140728003353

角度转弧度:弧度=角度×(π/180)

弧度转角度:角度=弧度×(180/π)

勾股定理

一个直角三角形直角所对内的斜边的平方等于其他两个边的平方和。三角形的斜边是它的最长的边,如图1.10 所示。

QQ截圖20140728004002

 

如果斜边用h 表示,勾股定理可以写成:

·1

两边取平方根得:

QQ截圖20140728004137

 

这意味着如果我们知道一个直角三角形的任意两个边的长度,就可以轻松地找到第三边。

直角三角函数

Image(12)

α的正弦sinα=b/c;(对边÷斜边)

α的余弦cosα=a/c;(邻边÷斜边)

α的正切tanα=b/a;(对边÷邻边)

当已知角度时,就用正弦、余弦或正切函数得到对应的三角函数值; 反之,如果要想得到角度,就应该利用反三角函数计算。

1.1.4 向量

一个向表达了两个性质:方向和大小。1.16 右边显示了份子原点处的向量(9, 6)。

QQ截圖20140728005001

向量运算

(以下内容来自3D数学基础:图形与游戏开发)

1 零向量

零向量是唯一大小为零的向量,它的每一维都是零,零向量也是惟一一个没有方向的向量。其实零向量表示的就是“没有位移”,就像标量零表示“没有数量”一样。

Image

1.2 负向量

要得到任意维向量的负向量,只需要简单地把每个分量都变负即可。数学表达式为:

Image(1)

几何解释:向量变负,将得到一个和原来向量大小相等,方向相反的向量。(向量在图中的位置是无关紧要的,只有大小和方向才是最重要的)。

Image(2)

1.3 向量大小

其实向量的大小和方向都没有在向量的数学表示中明确的表示出来。所有向量的大小是需要计算的,向量的大小也常被称作向量的长度或

n维向量大小的计算公式如下图:

Image(3)

线性代数中,向量的大小用向量两边双竖线表示,这和标量的绝对值在标量两边加单竖线表示类似。

1.4 标量与向量的乘法

虽然标量与向量不能相加,但它们能相乘。结果得到一个向量,与源向量平行,但长度不同或方向相反。

标量和向量的乘法非常直接,将向量的每一个分量都与标量相乘即可。

Image(4)

1.5 标准化向量

对许多向量,我们只关心它的方向而不关心其大小,这样的情况下,使用单位向量将非常方便。

单位向量就是大小为1的向量,单位向量经常也被称作标准化向量。

对于任意非零向量v,都能计算出一个和v方向相同的单位向量 v‘ 这个过程被称作向量的标准化,要标准化向量,将向量除以它的大小即可。

Image(5)

零向量不能被标准化。数学上这是不允许的,因为将导致除零。几何上也没有意义,因为零向量没用方向。

1.6 向量的加法与减法

如果两个向量的维数相同,那么它们能相加,或相减。结果向量的维数与原向量相同。向量加减法的记法和标量加减的记法相同。

两个向量相加或相减,将对应分量相加即可。

Image(6)

(1)向量不能与标量或维数不同的向量相加减。

(2)和标量加法一样,向量加法满足交换律,但向量减法不满足交换律。

1.7 向量点乘

向量点乘也常称作向量内积。

向量点乘就是对应分量乘积的和,结果是一个标量。

Image(7)

点乘结果描述了两个向量的“相似”程度,点乘结果越大,两个向量越相近。

Image(8)

1、判断是否垂直,如果A·B=0,那么A⊥B。

2、点乘结果的正负,如果A·B<0,那么Θ>90°,如果A·B>0,那么Θ<90°,其中Θ为向量A和向量B之间的夹角。

3、两向量之间的夹角,A·B=||A|| ||B||  cosΘ,其中Θ为向量A和向量B之间的夹角。

1.8 向量差乘

向量叉乘又叫叉积,仅可应用于3D向量。

Image(9)

叉乘得到的向量垂直于原来的两个向量。

Image(10)

Image(11)

C++向量封装类:

#ifndef __VECTOR3_H__#define __VECTOR3_H__ #include <math.h> ///////////////////////////////////////////////////////////////// Vector3类  简单的3D向量类/////////////////////////////////////////////////////////////// class Vector3{public:    float x, y, z; // 构造函数     // 默认构造函数,不执行任何操作    Vector3() {}     // 拷贝构造函数    Vector3(const Vector3 &a) : x(a.x), y(a.y), z(a.z) {}     // 带参数的构造函数,用三个值完成初始化    Vector3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {} // 标准对象操作     // 重载“=”操作符    Vector3& operator =(const Vector3 &a)    {        x = a.x; y = a.y; z = a.z;        return *this;    }     // 重载“==”操作符    bool operator ==(const Vector3 &a) const    {        return x==a.x && y==a.y && z==a.z;    }     // 重载“==”操作符    bool operator !=(const Vector3 &a) const    {        return x!=a.x || y!=a.y || z!=a.z;    } // 向量运算     // 向量归零    void zero() { x = y = z = 0.0f; }     // 重载一元“-”运算符    Vector3 operator -() const { return Vector3(-x, -y, -y); }     // 重载二元“+”和“-”运算符    Vector3 operator +(const Vector3 &a) const    {        return Vector3(x+a.x, y+a.y, z+a.z);    }     Vector3 operator -(const Vector3 &a) const    {        return Vector3(x-a.x, y-a.y, z-a.z);    }     // 与标量的乘、除法    Vector3 operator *(float a) const    {        return Vector3(x*a, y*a, z*a);    }     Vector3 operator /(float a) const    {        float oneOverA = 1.0f/a;        return Vector3(x*oneOverA, y*oneOverA, z*oneOverA);    }     // 重载自反运算符    Vector3& operator +=(const Vector3 &a)    {        x+= a.x; y+= a.y; z+= a.z;        return *this;    }     Vector3& operator -=(const Vector3 &a)    {        x-= a.x; y-= a.y; z-= a.z;        return *this;    }     Vector3& operator *=(const Vector3 &a)    {        x*= a.x; y*= a.y; z*= a.z;        return *this;    }     Vector3& operator /=(float a)    {        float oneOverA = 1.0f/a;        x*= oneOverA; y*=oneOverA; z*= oneOverA;        return *this;    }     // 向量标准化    void normailze()    {        float magSq = x*x +y*y +z*z;        if ( magSq > 0.0f )        {            float oneOverMag = 1.0f / sqrtf(magSq);            x*= oneOverMag;            y*= oneOverMag;            z*= oneOverMag;        }    }     // 向量点乘,重载标准的乘法运算符    float operator *(const Vector3 &a) const    {        return x*a.x + y*a.y + z*a.z;    }}; ///////////////////////////////////////////////////////////////// 非成员函数/////////////////////////////////////////////////////////////// // 求向量模inline float vectorMag(const Vector3 &a){    return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z);} // 计算向量叉乘inline Vector3 crossProduct(const Vector3 &a, const Vector3 &b){    return Vector3(        a.y*b.z - a.z*b.y,        a.z*b.x - a.x*b.z,        a.x*b.y - a.y*b.x    );}  // 实现标量左乘inline Vector3 operator *(float k, const Vector3 &v){    return Vector3(k*v.x, k*v.y, k*v.z);} // 计算两点间距离inline float distance(const Vector3 &a, const Vector3 &b){    float dx = a.x-b.x;    float dy = a.y-b.y;    float dz = a.z-b.z;    return sqrtf(dx*dx + dy*dy + dz*dz);} ///////////////////////////////////////////////////////////////// 全局变量/////////////////////////////////////////////////////////////// // 提供一个全局零向量extern const Vector3 kZeroVector; #endif  // __VECTOR3_H__

1.2 物理学

本书中定义物理学如下:质量和能量以及它们之间互相作用的科学。游戏人工智能程序员常常会运用物理定律进行工作,特别是与运动有关的物理定律,即在这部分会介绍的内容。

1.2.1 时间

时间是一个标量(用它的大小就可以完全确定,没有方向),用秒来度量,简写成s。

1.2.2 距离

距离(一个标量)的标准单位是m (米)。

1.2.3 质量

质量是一个标量,用千克度量,简写成kg。质量是一个事物的总量的度量(不包括外力)。

1.2.4 位置

位置是相对于质心来度量的属性,质量的中心是物体的平衡点。假想在这一点上系一根绳子悬挂物体,物体可以在任何一个位置都保持平衡。另一
个想象质心的好方法是把它看作物体内所有质量的平衡位置。

1.2.5 速度

速度是一个矢量(一个具有大小和方向的量),表达了距离相对于时间的变化率。度量速度的标准单位是mls (米每秒)。它用数学公式表达为:

QQ截圖20140728012001_thumb[1]

Δx表示距离上的变化,结束时候的距离减去开始移动时候的距离。Δt代表速度上的变化,结束时的时间减去开始移动时候的时间。

1.2.6 加速度

加速度是一个矢量,表达的是在时间段上速度的变化率,用米每二次方秒来度量,写作m/s²。加速度可以用数学式表达为:

QQ截圖20140728013653_thumb[1]

1.2.7 力

力( Force) 是可以改变物体的速度或者运动线路的量。

我们知道如果施加在一个物体上的合力是非零的,就在该力的方向上产生了一个加速度;但是加速度是多少?答案是加速度的大小a 与物体的质量m 成反比,与所施加的合力F 成正比。这个关系可以用下式给出:

QQ截圖20140728013156_thumb[1]

更多情况下,你将会看到写成这样的公式:

QQ截圖20140728013254_thumb[1]

使用这个公式,如果我们知道一个物体的加速度有多大,并且知道它的质量,就可以计算施加在它上面的合力。

例如,如果一个物体的质量为2000kg ,井且它的加速度为1.5m/s²,施加在它上面的合力是:

QQ截圖20140728013613_thumb