游戏中的三维数学

一、点和矢量

(一)坐标系分类

  • 笛卡尔坐标系;
  • 圆柱坐标系;
  • 球坐标系;

通常来说笛卡尔坐标系是我们最常用的坐标系,但我们同样要根据不同的情况来选择合适的坐标系,例如我们在做一些环绕动画的时候,采用圆柱坐标系可以更简单。

在三维笛卡尔坐标系中又分为左右手坐标系,用左右手来方便做记忆,大拇指指向X轴,食指指向Y轴,中指指向Z轴,3指垂直即可建立模型。左右坐标系的转换只需要把一个轴转换,保留另外两个轴的方向不变即可。对于三维图形程序员来说,一般以左手坐标系工作,并且Y轴向上,X轴向右,Z轴远离观察者(摄像机朝向),因此在三维图形渲染至二维屏幕时,Z坐标的增加就会增加景深。

(二)矢量运算

  • 矢量与标量的乘法:

    通常矢量与标量相乘都是保留矢量的方向,对矢量的模进行缩放。当然每个轴上的缩放因子也可以不相同,即非统一缩放,可表示为矢量与缩放矢量的分量积(反射光量可以使用RGB色值的分量积来计算)。

    S x A = (SxAx, SyAy, SzAz)

  • 加减法:

    矢量加减法多用于合成运算,点与方向的运算。

    • 方向 + 方向 = 方向
    • 方向 - 方向 = 方向
    • 点 + 方向 = 点
    • 点 - 点 = 方向
    • 点 + 点 = 无意义

(三)模

矢量的模是个标量,表示矢量在三维空间中的长度。

(四)应用

  • 矢量加减法可以用来刷新运动物体每帧的位置;
  • 球体相交测试的时候用矢量减法,模以及浮点比较来进行判断(在进行模运算的时候,计算平方根通常是费时的操作,所以在不影响准确性的情况下应该尽量改用模的平);

(五)矢量乘法

矢量的乘法有很多种,游戏编程中常见的有2种:

  • 点积:

    两个矢量的点积结果是一个标量,为两个矢量中每对分量乘积之和。

    A · B = AxBx + AyBy + AzBz

    点积也可以写成两个矢量的模相乘再乘以两矢量夹角的余弦。

    A · B = |A||B|cosθ

    点积符合交换律,加法上的分配律,标量乘法的结合律。

    点击判定:点击非常适合用来判断两矢量是否共线或垂直,或测试两矢量是否大致在相同或相反方向。

    • 共线:(A · B) = |A||B| = AB
    • 共线但是相反方向:(A · B) = -AB
    • 垂直:(A · B) = 0
    • 相同方向:(A · B) > 0
    • 相反方向:(A · B) < 0
    • 向量投影:给定两个向量v和n,可以把向量v分解为平行和垂直n的两个分量v1,v2。v1 = n(v·n)/|n|2,v2 = v - v1。
  • 叉积:

    两个矢量的叉积会产生一个垂直于原来两个矢量的矢量,叉积运算只定义在三维空间。

    A x B = [(AyBz - AzBy), (AzBx - AxBz), (AxBy - AyBx)]

    |A x B| = |A||B|sinθ

    若A和B为平行四边形的两条边,其面积为两矢量叉积的模|A x B|。

    叉积可以用来求法向量,力矩等。

    点和矢量的线性插值,用来计算两个已知点的中间点。

    L = LERP(A, B, θ) = (1-θ)A + θB

    = [(1-θ)Ax + θBx, (1-θ)Ay + θBy, (1-θ)Az + θBz]

    LERP函数是两矢量的加权平均。

关于向量相关的类我们可以在很多游戏引擎里面有看过,封装的方法也都是大同小异,这里介绍下封装过程中需要注意的细节:

  • 数据类型:float还是double,根据实际的需求而定;
  • 使用const成员函数;
  • 使用const引用参数传地址避免以值传递调用一次构造提高效率,而且如果函数不是内联的,传值的方式会需要更多的堆栈空间和更长的参数压栈时间。
  • 无缺省初始化:缺省构造函数不执行任何的初始化操作,因为向量类需要在严格要求速度的场合使用,建议不分配资源;
  • 不使用虚函数:1、使用虚函数,优化器不能产生成员函数的内联代码;2、虚函数需要指向虚函数表的指针,向量定义时指针必须初始化,会使对象的大小增加25%,而存储包含向量的大数组是一种很普遍的现象。
  • 全局常量:零
矩阵

4x4矩阵可表示任意三维变换,包括平移、旋转和缩放。仿射矩阵是一种4x4矩阵,它能维持直线在变换前后的平行性以及相对的距离比,但是不一定维持直线在变换前后的绝对长度及角度。

(一)矩阵乘法

P=AB,若A为缩放矩阵,B为旋转矩阵,则P等同于对点或矢量进行缩放和旋转变换。AB≠BA(AB不等于BA),矩阵乘法不符合交换律。

  • 逆矩阵

    矩阵A的逆矩阵能还原矩阵A的变换。若一个矩阵乘以它的逆矩阵,结果必然是单位矩阵。并非所有的矩阵都有逆矩阵。然而所有的仿射矩阵都有逆矩阵,可用高斯消去法或LU分解求之。

    A(Aˉ1) = I

    (ABC)ˉ1 = Cˉ1Bˉ1Aˉ1

  • 转置矩阵

    转置矩阵就是把原来的矩阵以主对角线为对称轴做反射,和逆矩阵相同,矩阵串接的转置为反向串接各个矩阵的转置。

齐次坐标

2x2矩阵来表示二维中的旋转:

3x3矩阵来表示三维中的旋转:

3x3矩阵是无法表示平移的:R + T = [(Rx + Tx), (Ry + Ty), (Rz + Tz)],虽然矩阵的乘法可以对元素进行相乘和相加,但是没有办法把T的分量放到3x3的矩阵中,使得与R相乘后产生(R+T)的值。

如果采用4x4矩阵就可以获得类似的和:

  • 变换方向矢量

    当用矩阵变换一个点时,平移、旋转、缩放都会施于该点上。但是,当用矩阵变换一个方向矢量时,就要忽略矩阵的平移效果。因为方向矢量本身并没有平移,加上平移会改变其模。

    严格地说四维的齐次坐标转换为三维的非齐次坐标的方法是把x,y,z分量除以w分量:

    [x y z w] = [x/w y/w z/w]

此公式表明,可设点的w分量为1,方向矢量的w为0。矢量除以w=1,并不影响点的坐标,矢量除以w=0则会产生无穷大。所以事实上三维空间的纯方向在四维齐次空间是位于无穷远的点。

基础变换矩阵

4x4矩阵可以切割为4个组成部分:

  • 左上的3x3矩阵U,代表旋转/缩放
  • 1x3平移矢量t

  • 平移

    平移矩阵的逆矩阵就是把t求反(即翻转tx,ty,tz的正负号)

  • 旋转

    纯旋转矩阵的逆矩阵即是该旋转矩阵的转置矩阵。

  • 缩放

    缩放矩阵的逆矩阵就是把Sx,Sy,Sz用倒数代替即可。

  • 4x3矩阵

    4x4的仿射矩阵中最右侧一定是一列[0 0 0 1]的矢量,所以可以略去第4列以节省内存。(在使用GPU做蒙皮的时候,要向顶点着色器传递大量的变换,所以为了节省空间、时间,通常会使用3x4矩阵)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-04 09:03:25

游戏中的三维数学的相关文章

游戏的物理和数学:Unity中的弹道和移动目标提前量计算

下载地址:http://yunpan.cn/cK6pCrpdhfbTd  提取码 5472 弹道计算是游戏里常见的问题,其中关于击中移动目标的自动计算提前量的话题,看似简单,其实还是挺复杂的数学.网上这方面的资料还真不多,而且都是写的含含糊糊.抽空总结一下自己的方法. 讨论的前提是,假设目标是在3D空间里以匀速直线方式运动. 1.直线弹道在不考虑重力和空气阻力影响的情况下,子弹的弹道呈直线运动.这种情况下,其实是个纯平面几何空间的问题,不需要微积分和线代知识.分析的情况如下图:        

ActionScript3游戏中的图像编程(连载十五)

1.3.1 HSB模式的色彩空间模型及其分支 第一次接触HSB模式的原理,是从以下这个地址开始的. http://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4 图 1.21是我从上面的文章拷过来的一张色彩空间示意图,可见HSB在业界至少还可以细分成HSL和HSV两种模式.它们都使用了三维坐标系来描述色彩值的分布. 图 1.21 色彩空间示意图 第一个属性是色相,它代表颜色的种类,如红,黄,绿属于

【转】游戏程序员的数学食粮05——向量速查表

原文:http://gad.qq.com/program/translateview/7172922 翻译:王成林(麦克斯韦的麦斯威尔)  审校:黄秀美(厚德载物) 这是本系列大家盼望已久的第五篇.如果你对向量了解不多,请先查看本系列的前四篇文章:介绍,向量基础,向量的几何表示,向量的运算. 这篇速查表会列举一些游戏中常见的几何问题,以及使用数学向量解决它们的方法. 基本向量运算的完整表单 首先,先复习一下. 首先我假设你有一个可用的向量类.它的功能大部分集中在2D上,但是3D的原理相同.差别只

漫谈游戏中的人工智能

写在前面   今天我们来谈一下游戏中的人工智能.当然,内容可能不仅仅限于游戏人工智能,还会扩展一些其他的话题. 游戏中的人工智能,其实还是算是游戏开发中有点挑战性的模块,说简单点呢,是状态机,说复杂点呢,是可以帮你打开新世界大门的一把钥匙.有时候看到知乎上一些可能还是前公司同事的同学的一些话,感觉还是挺哭笑不得的,比如这篇:http://zhi.hu/qu1h,吹捧机器学习这种玄学,对游戏开发嗤之以鼻.我只能说,技术不到家.Vision不够,这些想通过换工作可培养不来. 这篇文章其实我挺早就想写

游戏的物理和数学:弹道和移动目标提前量计算

弹道计算是游戏里常见的问题,其中关于击中移动目标的自动计算提前量的话题,看似简单,其实还是挺复杂的数学.网上这方面的资料还真不多,而且都是写的含含糊糊.抽空总结一下自己的方法.讨论的前提是,假设目标是在3D空间里以匀速直线方式运动.1.直线弹道在不考虑重力和空气阻力影响的情况下,子弹的弹道呈直线运动.这种情况下,其实是个纯平面几何空间的问题,不需要微积分和线代知识.分析的情况如下图:         虽然在3D空间飞行,但火炮命中时,命中点和火炮位置.飞机初始位置处于一个三角形上,只需要平面几何

游戏中角色曲线行走的算法

这几天工作中碰到一个需求:使游戏中的NPC角色以非直线的方式走到某一位置.角色在朝着目标位置移动时,有一定的左右偏移,但到达目标位置时不能有偏差.问题中已知的是平面上的两个二维坐标点表示起点与终点,最大的偏移范围.当给定一个时刻时,需要输出角色的当前位置. 首先我做的是将整个行走轨迹画出来,这里使用我写的一个软件:数学图形可视化工具,使用自己定义语法的脚本代码生成数学图形.该软件免费开源.QQ交流群: 367752815 脚本代码如下: vertices = 1000 t = from (0)

ActionScript3游戏中的图像编程(连载四十二)

2.3.4 Photoshop高度==Flash距离? 剩下高度一项了,跟距离相对应吗? 但是,高度以角度为单位,但距离却是像素,似乎拉不上关系.不过我们照样做下试验:先试一下Photoshop的高度.在调整的过程里发现,浮雕的厚度并没随着高度的增加而变大.只感觉到光影往某个方向微妙地移动着. 图 2.69~图 2.75展示了不同高度下的效果. 图 2.69 高度=0° 图 2.70 高度=15° 图 2.71 高度=30° 图 2.72 高度=45° 图 2.73 高度=60° 图 2.74

Unity制作游戏中的场景

Unity制作游戏中的场景 1.2.3  场景 在Unity中,场景(Scene)就是游戏开发者制作游戏时,所使用的游戏场景.它是一个三维空间,对应的三维坐标轴分别是X轴.Y轴和Z轴本文选自Unity 2D游戏开发从入门到精通清华大学出版社. 要创建一个新的场景,只需单击File|New Scene命令,或者按下快键键Ctrl+N,如图1-16所示. 图1-16  创建程序的命令,以及场景 默认情况下,新创建游戏项目的同时,也新创建了游戏的场景,只不过还没有保存罢了.使用快捷键Ctrl+S即可保

ActionScript3游戏中的图像编程(连载十六)

1.3.2 软件中的拾色器如何实现HSB的色彩空间模型 阅读本书的朋友恐怕很少有机会见到圆柱形的三维取色器,而HSB模式却是一个立体的空间.那么,软件里的颜色拾取器是如何在平面里体现出3D坐标系的呢?让我们从Windows调色板开始研究.图 1.22是Windows系统调色板的界面,抛开左侧的颜色列表不谈,我们可以把Windows调色板分为两个部分:一个二维的平面和一个一维的滑块.乍一看似乎跟之前的圆柱体空间扯不上任何关系,不过有没发现,最右侧那个一维的条是不是跟圆柱体的母线很像,从上而下呈现出