计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动。通常情况下,物体位置的变化包含三个基本的变化:平移、旋转和缩放,物体的运动也可以用这三个基本的运动形态的组合来描述。

图形学中物体运动的数学表述是:将点的初始位置坐标P0映射到经过平移、旋转、绽放后的新位置P1的过程。

平移:

平移就是在原始的三维空间坐标点上分别加上对应方向上的平移量:

旋转:

旋转分为两类:在二维平面和三维空间中的旋转。

二维平面上的旋转:

相对坐标注原点旋转角度θ:

以矩阵形式表述:

扩展到三维空间,先看简单的绕某一个坐标轴旋转的情况。

绕Z轴旋转:

绕X轴旋转:

绕Y轴旋转:

三维空间中绕指定的任意轴旋转变换可以分解为分别绕三个坐标轴的旋转变换和一个平移变换的叠加。

缩放变换是三个维度上分别乘一个缩放系数:

总结以上,可以看到变换后的坐标点除了平移变换是在原始坐标上加上一个平移向量外,旋转、缩放都是在原始坐标点上乘以一个变换矩阵。

为了把平移变换也统一成矩阵相乘的形式,引入了齐次坐标。齐次坐标就是将一个原来是N维的向量用一个N+1维向量来表示 。在齐次坐标中用4个分量来表示三维空间中的一个点,前三个分量跟普通三维坐标一样,第四个分量设置为1。

在齐次坐标下,平移变换可以表述为:

这样,在齐次坐标系下,三维空间的运动一一平移、旋转、缩放在形式上都统一为左乘一个变换矩阵的形式。

考察一个物体的运动,先进行一次平移,再进行一次旋转,两个运动可以表述为:

R*T也是一个4*4的变换矩阵,这个变换包含了一次平移和一次旋转的叠加。

推广到更复杂的变换,只需要在当前R*T矩阵上依次左乘上对应的变换矩阵,最终得到的变换矩阵包含了物体所有变换的叠加,而这一系列的变换只需要用初始坐标左乘上这个最终的变换矩阵就可以实现,这个矩阵就是“模型矩阵”。


例如对于三维空间中的一条直线,直线经过点(x0,y0,z0),并且方向为(a,b,c),则一个物体绕该直线旋转θ角度的运动变换可以分解为:

  • 平移(-x,-y,-z)平移到原点
  • 绕x轴旋转角度p使指定的旋转轴在x-z平面上
  • 绕y轴旋转角度q使指定的旋转轴与z轴重合
  • 绕z轴旋转角度 绕y轴旋转角度-q
  • 绕x轴旋转角度-p
  • 平移(x,y,z )

综上可以看到,模型矩阵描述了三维空间物体的一系列变换的信息。在物体为刚体模型(刚体是在运动中和受力作用后,形状和大小不变,而且内部各点的相对位置不变的物体)的情况下,物体的所有顶点通过左乘模型矩阵,就可以实现物体的指定运动,所以模型矩阵大大降低了运动模型的复杂度。

模型视图矩阵

在模型矩阵中,关心的是物体在运动之后在世界坐标系下位置坐标点的变化。更加普遍的情况是,我们更加关心物体相对于观察者的位置变化,而不仅仅是关于世界坐标系下的变化。例如观察者在一辆运动着的汽车中观察另一辆相向而行的汽车的变换,这时候观察者和被观察的物体都在运动。这种观察者也在移动的情况,在现实世界中更加普遍。这也增加了确定运动模型的复杂度。

所幸的是,我们可以从另一个角度看待这个问题,即观察者的位置和方向发生变化时(这个变换可以用一个模型矩阵来表述),可以看做是被观察的物体进行了观察者运动相反的运动,即需要在模型矩阵的基础上再左乘一个观察者变换矩阵的逆矩阵,这个逆矩阵称为“视图矩阵”,而这个视图矩阵跟模型矩阵相乘得到的矩阵就是所谓的“模型视图矩阵”。

物体左乘模型视图矩阵后获得的新的位置(形状),描述 的是当观察者和物体都在运动时,物体在观察者眼中坐标点(形状)的变化。

数学 就是这么奇妙,它先把一个很简单问题复杂化,然后再把它简单化,以彰显其牛逼之处。

OpenGL(五) 三维变换之模型视图矩阵的更多相关文章

  1. WEBGL学习【四】模型视图矩阵

    <html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...

  2. WebGL简易教程(六):第一个三维示例(使用模型视图投影变换)

    目录 1. 概述 2. 示例:绘制多个三角形 2.1. Triangle_MVPMatrix.html 2.2. Triangle_MVPMatrix.js 2.2.1. 数据加入Z值 2.2.2. ...

  3. [OpenGL ES 03]3D变换:模型,视图,投影与Viewport

    [OpenGL ES 03]3D变换:模型,视图,投影与Viewport 罗朝辉 (http://blog.csdn.net/kesalin) 本文遵循“署名-非商业用途-保持一致”创作公用协议 系列 ...

  4. SCARA——OpenGL入门学习五六(三维变换、动画)

    OpenGL入门学习(五) 此课为三维变换的内容,比较枯燥.主要是因为很多函数在单独使用时都不好描述其效果, 在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能 ...

  5. OpenGL模型视图变换、投影变换、视口变换的理解

    OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕向外). 产生目标场景的过程类似于用照相机进行拍照: (1)把照相机固定在三角架上,并让他对 ...

  6. 简单理解OpenGL模型视图变换

    前几天学习了OpenGL的绘图原理(其实就是坐标的不停变换变换),看到网上有个比较好的例程,于是学习了下,并在自己感兴趣的部分做了注释. 首先通过glMatrixMode(GL_MODELVIEW)设 ...

  7. WEBGL学习【八】模型视图投影矩阵

    <!--探讨WEBGL中不同图形的绘制方法:[待测试2017.11.6]--> <!DOCTYPE HTML> <html lang="en"> ...

  8. OpenGL chapter4 基础变换

    math3d库有两个数据类型,能够表示一个三维或四维向量: M3DVector3f M3DVector4f 4.3 理解投影 正投影 : 正交变换 透视投影 : 透视变换 表4.1 OpenGL变换术 ...

  9. three.js中的矩阵变换(模型视图投影变换)

    目录 1. 概述 2. 基本变换 2.1. 矩阵运算 2.2. 模型变换矩阵 2.2.1. 平移矩阵 2.2.2. 旋转矩阵 2.2.2.1. 绕X轴旋转矩阵 2.2.2.2. 绕Y轴旋转矩阵 2.2 ...

随机推荐

  1. 强力推荐微信小程序之简易计算器,很适合小白程序员

    原文链接:https://mp.weixin.qq.com/s/gYF7GjTRpeZNoKPAPI9aXA 1 概述 前几日QQ群里的朋友问我有没有计算器小程序案例,今天我们说下小程序计算器,然后就 ...

  2. PatentTips - Enhanced I/O Performance in a Multi-Processor System Via Interrupt Affinity Schemes

    BACKGROUND OF THE INVENTION This relates to Input/Output (I/O) performance in a host system having m ...

  3. 通过双重for循环来找到JSON中不反复的数据

    //通过双重for循环来找到JSON中不反复的数据 var count = 0; for ( i=0; i<json.length; i++) { for ( j=0; j<i; j++) ...

  4. Python爬虫之路——简单的网页抓图

    转载自我自己的博客:http://www.mylonly.com/archives/1401.html 用Python的urllib2库和HTMLParser库写了一个简单的抓图脚本.主要抓的是htt ...

  5. HDU 1013 Digital Roots 题解

    Problem Description The digital root of a positive integer is found by summing the digits of the int ...

  6. 并查集(disjoint set)的实现及应用

    这里有一篇十分精彩.生动的 并查集详解 (转): "朋友的朋友就是朋友"⇒ 传递性,建立连通关系 disjoint set,并查集(一种集合),也叫不相交集,同时也是一种树型的数据 ...

  7. 剪枝法观点下的旅行商问题(TSP)

    1. 构建基本的穷举搜索骨架 int n; int dst[100][100]; int best; const int INF = 987654321; // 初始状态下,path 存入第一节点,v ...

  8. 【48.47%】【POJ 2524】Ubiquitous Religions

    Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 32364 Accepted: 15685 Description There a ...

  9. Java提高:采用异常链传递异常

    一.分析 异常需要封装,但是仅仅封装还是不够的,还需要传递异常.一个系统的友好型的标识,友好的界面功能是一方面,另一方面就是系统出现非预期的情况的处理方式了. 二.场景 比如我们的JEE项目一般都又三 ...

  10. Linux系统编程——线程私有数据

    在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...