1变换

在3D游戏的整个开发过程中,通常需要以某种方式对一系列的向量进行变换。通常用到的变换包括平移,缩放和旋转。

1.1通用变换

通常可将n x n可逆矩阵M看成是一个从坐标系到另一个坐标系的变换矩阵。M的列给出了坐标系从原坐标系到新坐标系的映射。例如M是一个n x n可逆矩阵,当M与向量(1,0,0),(0,1,0)和(0,0,1)相乘时,可以得到

类似地,M-1的列给出了坐标轴从新坐标轴系到原坐标轴系的映射。这样对于任意给定的线性无关的向量U,V,W可以构造一个变换矩阵,该矩阵将这些向量映射到向量(1,0,0),(0,1,0)和(0,0,1)。

多个变换可以串联起来,并且可以将多个变换矩阵的乘积用一个矩阵来表示。假设需要先用矩阵M后用矩阵G对一个对象进行变换,由于乘积满足结合律,对于任意向量P都有G(MP)=(GM)P,因此只需存储GM的乘积得到的矩阵,将该矩阵作为对象的变换矩阵即可。这样就可以对定点进行多次变换,而存储空间不变。

正交矩阵是一种其转置矩阵等于其逆矩阵的矩阵。正交矩阵只能用于表示旋转和反射的组合。

反射指在某一方向上将点进行镜像的一种运算。例如,矩阵

以xy平面为对称面对一点的z坐标进行反射。

手向性

在三维空间中,有3D向量V1,V2,V3构成的坐标系的基&具有手向性。对于右手基,有(V1*V2). V3>0。也就是说,在一个右手坐标系中,v1,v2的叉积的方向与v3的方向形成一个锐角。如果&是一个正交规范的右手基,则有v1*v2=v3。若(v1*v2).v3<0,那么&是左手基。

进行奇数次反射操作就会改变手向性,偶数次反射相当于一次旋转。通过观察3x3矩阵的行列式,就可以判定矩阵是否存在反射。若M的行列式是负的,则存在反射,用M对任意基的向量进行变换操作后,基的手向性都会发生改变。如果行列式是正的,那么M不改变手向性。

正交矩阵M的行列式的值只能是1或-1.若detM=1,矩阵M只存在旋转;如果为-1,那么M表示旋转之后再进行一次反射。

1.2缩放变换

简单来说,对于统一缩放可以理解为向量P乘以一个常数a,即P’ = aP。在三维空间里可以用矩阵的乘积表示。

如果是在xyz轴以不同的值进行缩放向量,那么可以这种缩放为非统一缩放。

如果在3个任意轴上进行非统一缩放,就要用到复杂的缩放过程。假设以系数a沿U轴方向,以系数b沿V轴方向,以系数c沿W轴方向进行缩放,可以先从坐标系(U,V,W)变换到坐标系(i,j,k),然后在(i,j,k)坐标系进行缩放运算,最后在还原到(U,V,W)坐标系。

1.3旋转变换

首先讲一下在二维平面上的旋转,也就是在平面直角坐标系上进行旋转。假设一个向量P(Px,Py),要想求得相对于它自身旋转a度角后的向量P’。我们就需要根据P逆时针旋转90度得到其正交的向量Q(-Py,Px)。可以将P,Q看做该坐标系的一对正交基,则P’可以被P和Q表示为:

P’ = Pcosa + Qsina; (1)

可以确定P’的x,y分量为:

可以改写成矩阵的形式:

引申一下:将单位矩阵的第三行和第三列加入P’矩阵中可得:

,该矩阵是绕z轴的三维旋转。

同样可以得到绕x轴和y轴旋转角度的3x3旋转矩阵。

绕任意轴旋转

假设向量P绕一个任意轴旋转Θ角,这里的任意轴以单位向量A表示,可以将向量P分解为垂直于和平行于A的分量P1, P2。由于平行分量P2在平行于A,则在旋转过程中保持不变,主要求的是P1的旋转。

由于A是一个单位向量,对于P在A上的投影,可以表示为:projAP = (A.P)A;

P垂直于A的分量可表示为:perpAP = P – (A.P)A;

现将垂直于A的分量进行旋转,然后加上projAP就可以得到最终的旋转结果。

垂直分量的旋转是如何得到的呢?

垂直分量的旋转是在垂直于A轴的平面内进行的。可以用perpAP与perpAP逆时针方向旋转90度所形成的向量的线性组合来表示旋转后的向量。如上图所示,假设a是原向量P和A轴之间的夹角。perpAP的长度等于||P||sina,那么perpAP绕A轴逆时针旋转90度的向量perpAP’就是A与P的叉积。

那么perpAP旋转Θ角可以表示为:[P-(A.P)A]cosΘ + (A x P)sinΘ (2)

(2)式的推出可以参考(1)式。

加上projAP = (A.P)A,就可以得到P绕A轴的旋转公式:

P’ = PcosΘ + (A x P)sinΘ + A(A.P)(1-cosΘ);  (3)

将(3)式换成矩阵的表达形式:

合并公式中的相同项,令C=cosΘS=sinΘ,得到表示向量绕A轴旋转Θ角的旋转矩阵RA(Θ).

1.4齐次坐标

关于平移操作,不能用3 x 3矩阵表示,把点P从一个坐标系平移到另一个坐标系,只需要简单地添加偏移向量,不会影响到坐标轴的方向和尺度。

P’ = MP + T      (4)

其中M为3 x 3可逆矩阵,T是3D平移向量。利用(4)式进行两次操作可得到:

 (5)

若是要进行n次操作时,必须知道每次变换过程中的矩阵分量MnMn-1和平移分量MnTn-1+Tn

我们利用四维变换可以将M和T统一起来,就可以建立一个四维4 x 4矩阵来表示平移操作。方法是给3D点P增加一个坐标,并将这个扩展的第四个坐标称之为w坐标,其值设为1。

  (6)

将矩阵F乘以向量(Px,Py,Pz,1),就等价于(4)式对向量的x,y,z坐标进行变换,同时保持w为1。

从公式(4)中可以解出  (7)

因此可以从公式(6)中得到4 x 4矩阵F的逆矩阵F-1为:

(8)

可以验证(8)式的正确性:

3D游戏与计算机图形学中的数学方法-变换的更多相关文章

  1. 3D游戏与计算机图形学中的数学方法-四元数

    说实话关于四元数这一节真的是不好懂,因为里面涉及到好多数学知识,单说推出来的公式就有很多.不怕大家笑话,对于四元数的学习我足足花了两天的时间,包括整理出这篇文章.在前面一章我写到了“变换”,这也是总结 ...

  2. 3D游戏与计算机图形学中的数学方法-点线面

    <易传·系辞上传>:”易有太极,是生两仪,两仪生四象,四象生八卦.” 借用一下古代先人们的智慧引一下本文的主题-三维图形中的点线面,在三维几何中也有一句话可以和上面的话相对应:由点成线,由 ...

  3. 3D游戏与计算机图形学中的数学方法-视截体

    视截体用来表示一个空间的范围,位于这个空间范围内的三维场景的任何物体都可以被看到. 视截体由六个平面围成,其中的四个平面与场景的边界相对应,分别被称为左,右,底,顶视截面.另外两个平面称为近视截面和远 ...

  4. Mathematics for Computer Graphics数学在计算机图形学中的应用 [转]

    最近严重感觉到数学知识的不足! http://bbs.gameres.com/showthread.asp?threadid=10509 [译]Mathematics for Computer Gra ...

  5. 3D游戏开发之UE4中的集合:TSet容器

    好久没有更新了,最近一直在老家过年,网络不通的,今天才有时间更新一集. 一.TSet<T>是什么 UE4中,除了TArray动态数组外,还提供了各种各样的模板容器.这一节,我们就介绍集合容 ...

  6. 计算机图形学中使用Turbo C++画图步骤

    一.下载安装Turbo C++ 我安装的是Turbo C++ 3.2.2.0下载链接 二.画图 1.打开Turbo C++,点击右下角start turbo C++ 2.点击file ->new ...

  7. JS中的数学方法

    1 . Math.ceil()      向上取整 2.  Math.floor()     向下取整 3. Math.round()    四舍五入取整 4.  Math.random()   生成 ...

  8. Java中的数学方法

    直接用代码 public class TestNumber { public static void main(String[] args) { float f1 = 5.4f; float f2 = ...

  9. 计算机图形学学习方法和相关书籍,做游戏,GIS,虚拟现实,三维引擎的都能够看看.

    本书參照<<图形学扫盲>> 整理的,原文内容引子: http://www.cppblog.com/lai3d/archive/2008/12/30/70796.html 前言: ...

随机推荐

  1. OpenGl学习 SelectObject函数

    SelectObject 函数功能:该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象.   函数原型:HGDIOBJ SelectObject(HDC hdc, HGDIOB ...

  2. excel错误:外部表不是预期的格式 错误

    环境:win7+iis7+Office2007 在asp.net网站中导出Excel文件后,再把文件导入到数据库中. 读取Excel文件时,打开连接出错. 错误为:外部表不是预期的格式 解决:检查了一 ...

  3. iOS之Sqlite3封装

    一.代码下载 代码下载地址 二.实例效果展示 imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="效果图二.png&q ...

  4. gtk-gnash大量占用cpu解决办法

    http://blog.csdn.net/papenghan/article/details/7727955 gnash是一个firefox的flash插件版本.当使用firefox打开含有falsh ...

  5. LeetCode: Evaluate Reverse Polish Notation 解题报告

    Evaluate Reverse Polish Notation Evaluate the value of an arithmetic expression in Reverse Polish No ...

  6. 【Java】包装类总结

    Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数 ...

  7. java 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())

    JAVA中有3种方式可以终止正在运行的线程 ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()方法强行终止线程.但stop()方法已经过期了,不推荐使用 ③使用中断机制i ...

  8. RSA算法工具

    RSA算法工具-生成密钥对(生成密钥对) RSA算法工具-解析密钥对(导入密钥对,解析密钥对) RSA测试工具-计算分量(输入P,Q,E,计算出N,DP,DQ,Qinv)

  9. JAVA-JSP声明语句

    相关资料: <21天学通Java Web开发> 结果总结: 1.<%! %>声明的变量为全局变量. 实例代码: <html> <head> <ti ...

  10. 【C#】事件(Event)和代理/委托(Delegate)

    代理(Delegate)的例子 delegate void MyDelegate(string str,int index); // 声明代理 class Test { public static v ...