OpenGL入门学习——第五课 三维的空间变换
opengl 图形的变换与裁剪
![opengl 图形的变换与裁剪](https://img.taocdn.com/s3/m/2e8db740336c1eb91b375d05.png)
二维显示
坐标系:窗口坐标系、规格化设备坐标系与 屏幕的物理坐标系 变换:设备变换、视窗变换
25
三维变换流程图
局部坐标系
造型变换
世界坐标系
取景变换
视点坐标系
投影变换
图像坐标系
设备变换
规格化设备 坐标系
视窗变换
屏幕坐标系
26
三维变换中的各种坐标系
27
场景坐标系和模型变换
几何场景建立于世界坐标系中 场景中的具体物体与局部坐标系相联系
局部坐标系可以简化物体的定义 物体={标准体素,变换}
造型变换:
物体从局部坐标系到世界坐标系的变换 三维线性和非线性变换
28
三维模型变换:平移
三维平移T:三维点P(x,y,z)移动(tx,ty,tz)后, 得到点P'(x',y',z')
x′ 1 ′ y = 0 z′ 0 1 0 0 1 0 0 0 t x x 0 t y y 1 t z z 0 1 1
0 x 0 y 1 1
θ ϕ
7
二维缩放
对于进行放缩的变换公式
y
x′ sx ′ y = 0 1 0
0 sy 0
0 x 0 y 1 1
S ( sx , s y )
其中sx和sy分别为x和y分量的放缩比例
x
8
剪切变换(Shear)
沿X-轴方向的剪切变换
Y (x,y) (x',y')
α
X
x′ 1 tgα ′ y = 0 1 1 0 0
三维空间旋转变换公式
![三维空间旋转变换公式](https://img.taocdn.com/s3/m/26d5c833f56527d3240c844769eae009581ba2d1.png)
三维空间旋转变换公式摘要:一、引言二、三维空间旋转变换的概念1.旋转变换的定义2.三维空间旋转变换的分类三、三维空间旋转变换公式1.欧拉角公式2.旋转矩阵公式3.旋转四元数公式四、三维空间旋转变换的应用1.坐标变换2.刚体运动五、结论正文:一、引言在三维空间中,物体的运动不仅仅包括平移,还包括旋转。
旋转变换是描述物体在三维空间中围绕某个轴旋转的变换。
了解三维空间旋转变换的公式,对于研究和分析物体在三维空间中的运动具有重要意义。
二、三维空间旋转变换的概念1.旋转变换的定义三维空间旋转变换,是指将一个向量从一个坐标系旋转到另一个坐标系的变换。
这种变换可以通过一个旋转矩阵或四元数来表示。
2.三维空间旋转变换的分类根据旋转轴的不同,三维空间旋转变换可以分为以下三种:(1)绕x轴旋转(2)绕y轴旋转(3)绕z轴旋转三、三维空间旋转变换公式1.欧拉角公式欧拉角公式是一种常用的表示三维空间旋转变换的方法,它用三个角度来描述旋转。
以绕x、y、z轴分别为旋转轴的旋转变换为例:(1)绕x轴旋转:Rx = |cosθ| |0, 0, 1| + |sinθ| |1, 0, 0|(2)绕y轴旋转:Ry = |cosφ| |0, 1, 0| + |sinφ| |0, 0, -1|(3)绕z轴旋转:Rz = |cosψ| |1, 0, 0| + |sinψ| |0, -1, 0|2.旋转矩阵公式旋转矩阵是一种更简洁的方式来表示三维空间旋转变换。
以绕x、y、z轴分别为旋转轴的旋转变换为例:(1)绕x轴旋转:Rx = |1, 0, 0||0, cosθ, -sinθ||0, sinθ, cosθ|(2)绕y轴旋转:Ry = |cosφ, 0, sinφ||0, 1, 0||-sinφ, 0, cosφ|(3)绕z轴旋转:Rz = |cosψ, -sinψ, 0||sinψ, cosψ, 0||0, 0, 1|3.旋转四元数公式四元数是一种更简洁的表示三维空间旋转变换的方法。
OpenGL中的三维处理
![OpenGL中的三维处理](https://img.taocdn.com/s3/m/1afac46648d7c1c708a1459b.png)
OpenGL通过相机模拟、可以实现计算机图形学中最基本的三维变换,即几何变换、投影变换、裁剪变换、视口变换等,同时,OpenGL还实现了矩阵堆栈等。
理解掌握了有关坐标变换的内容,就算真正走进了精彩地三维世界。
一、OpenGL中的三维物体的显示(一)坐标系统在现实世界中,所有的物体都具有三维特征,但计算机本身只能处理数字,显示二维的图形,将三维物体及二维数据联系在一起的唯一纽带就是坐标。
为了使被显示的三维物体数字化,要在被显示的物体所在的空间中定义一个坐标系。
这个坐标系的长度单位和坐标轴的方向要适合对被显示物体的描述,这个坐标系称为世界坐标系。
世界坐标系是始终固定不变的。
OpenGL还定义了局部坐标系的概念,所谓局部坐标系,也就是坐标系以物体的中心为坐标原点,物体的旋转或平移等操作都是围绕局部坐标系进行的,这时,当物体模型进行旋转或平移等操作时,局部坐标系也执行相应的旋转或平移操作。
需要注意的是,如果对物体模型进行缩放操作,则局部坐标系也要进行相应的缩放,如果缩放比例在案各坐标轴上不同,那么再经过旋转操作后,局部坐标轴之间可能不再相互垂直。
无论是在世界坐标系中进行转换还是在局部坐标系中进行转换,程序代码是相同的,只是不同的坐标系考虑的转换方式不同罢了。
计算机对数字化的显示物体作了加工处理后,要在图形显示器上显示,这就要在图形显示器屏幕上定义一个二维直角坐标系,这个坐标系称为屏幕坐标系。
这个坐标系坐标轴的方向通常取成平行于屏幕的边缘,坐标原点取在左下角,长度单位常取成一个象素。
(二)三维物体的相机模拟为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模拟的方式,假定用相机来拍摄这个世界,那么在相机的取景器中,就存在人眼和现实世界之间的一个变换过程。
图一、相机模拟OpenGL中的各种坐标变换从三维物体到二维图象,就如同用相机拍照一样,通常都要经历以下几个步骤:1、将相机置于三角架上,让它对准三维景物,它相当于OpenGL中调整视点的位置,即视点变换(Viewing Transformation)。
三维空间旋转变换公式
![三维空间旋转变换公式](https://img.taocdn.com/s3/m/7dc1fac0760bf78a6529647d27284b73f3423670.png)
三维空间旋转变换公式【原创实用版】目录1.三维空间的基本概念2.三维空间旋转变换公式的定义3.三维空间旋转变换公式的应用4.结论正文一、三维空间的基本概念三维空间是一个由三个相互垂直的维度组成的空间,通常用 x、y、z 表示。
在三维空间中,每个点都具有三个坐标值,即 x 坐标、y 坐标和 z 坐标。
三维空间是几何学、物理学等学科中常用的概念,它有助于我们更好地理解和描述现实世界中的物体和现象。
二、三维空间旋转变换公式的定义三维空间旋转变换公式是指在三维空间中,将一个点或一组点按照某个轴进行旋转后,其坐标值的计算公式。
在三维空间中,一个点围绕某个轴旋转后,其坐标值的变化可以通过旋转矩阵来表示。
具体来说,假设有一个点 P(x, y, z),它围绕 z 轴逆时针旋转θ角后,其坐标值变为 P"(x", y", z"),那么可以得到以下旋转变换公式:x" = x cosθ - z sinθy" = y cosθ - z cosθz" = x sinθ + z cosθ其中,θ表示旋转的角度,x、y、z 和 x"、y"、z"分别表示旋转前后的坐标值。
三、三维空间旋转变换公式的应用三维空间旋转变换公式在实际应用中具有广泛的应用价值。
例如,在计算机图形学中,利用旋转变换公式可以实现三维图形的旋转效果;在物理学中,利用旋转变换公式可以研究物体在三维空间中的运动轨迹;在工程技术中,利用旋转变换公式可以进行三维空间的坐标转换,从而提高计算精度和效率。
四、结论三维空间旋转变换公式是描述点在三维空间中旋转后坐标值变化的重要工具,它有助于我们更好地理解和描述现实世界中的物体和现象。
OpenGL入门教程(精)
![OpenGL入门教程(精)](https://img.taocdn.com/s3/m/0bc6be7df46527d3240ce036.png)
4、把解压得到的 glut.dll 和 glut32.dll 放到操作系统目录下面的 system32 文件夹内。(典型的位置为: C:\Windows\Sy st em32) 第三步,建立一个 OpenGL 工程 这里以 VisualStudio2005 为例。 选择 File->New->Project,然后选择 Win32 Console Application,选择一个名字,然后按 OK。 在谈出的对话框左边点 Application Settings,找到 Empty project 并勾上,选择 Finish。 然后向该工程添加一个代码文件,取名为“OpenGL.c”,注意用.c 来作为文件结尾。 搞定了,就跟平时的工程没什么两样的。 第一个 OpenGL 程序
在 glutDisplayFunc 函数中,我们设置了“当需要画图时,请调用 myDisplay 函数”。于是 myDisplay 函数就 用来画图。观察 myDisplay 中的三个函数调用,发现它们都以 gl 开头。这种以 gl 开头的函数都是 OpenGL 的标准函数,下面对用到的函数进行介绍。 1、glClear,清除。GL_COLOR_BUFFER_BIT 表示清除颜色,glClear 函数还可以清除其它的东西,但这里 不作介绍。 2、glR ect f,画一个矩形。四个参数分别表示了位于对角线上的两个点的横、纵坐标。 3、glFlush,保证前面的 OpenGL 命令立即执行(而不是让它们在缓冲区中等待)。其作用跟 fflush(stdout) 类似。
OpenGL 入门教程
1.第一课:
说起编程作图,大概还有很多人想起 TC 的#include < graphics.h>吧? 但是各位是否想过,那些画面绚丽的 PC 游戏是如何编写出来的?就靠 TC 那可怜的 640*480 分辨率、16 色来做吗?显然是不行的。
[课件]第5章 三维图形变换PPT
![[课件]第5章 三维图形变换PPT](https://img.taocdn.com/s3/m/80c52cfa7f1922791788e807.png)
5.1 三维图形齐次坐标变换矩阵
• 齐次变换矩阵提供一个三维空间中包括平移、旋转、透 视、投影、反射、错切和比例等变换在内的统一表达式, 使得物体的变换可在统一的矩阵形式下进行。 旋转、错切等 透视变换
平移变换
比例变换
5.2 图形的三维几何变换
三维图形变换可以在二维图形变换方法基础上增 加对 z 坐标的考虑而得到,其变换也为平移、缩放、 旋转、对称、错切等五种变换。在二维图形变换的讨 论中我们已经使用了齐次坐标表示法,其变换矩阵是 3×3阶矩阵。对于三维空间,则变换矩阵需要是4×4 阶矩阵。在三维图形变换的讨论中,仍采用假定坐标 系不动,图形变换的方式。并且假定变换是在右手坐 标系下进行。
式中sx、sy和sz分别表示点P(x, y, z)沿 X、 Y及 Z轴方 向相对坐标原点的比例变换系数。系数可赋予任何正数值, 当值小于1时缩小图形,值大于1则放大图形。当sx、sy和sz 被赋予相同值时,使图形产生三个坐标轴方向相对比例一 致的变换, sx、sy和sz值不等时则产生不一致的变换。
相对于给定点Pc(xc,yc,zc)的比例变换的矩阵表示为:
5.2.2 缩放变换 x' x s x 相对于原点的 缩放变换的表示式为: y ' y s y
z' z s z
s x 0 矩阵表示是: x ' y ' z ' 1 x y z 1 0 0
0 0 0 s 0 0 y 0 s z 0 0 0 1
(3) 绕Y轴旋转变换
绕Y轴旋转时,图形上各点y坐标不变,x 、z坐标的变化 相当于在XZ二维平面内绕原点旋转。旋转变换公式为:
y z sin y x' xcos y' y z xsin zcon y y
OpenGL空间(坐标系)变换
![OpenGL空间(坐标系)变换](https://img.taocdn.com/s3/m/b92d3a082379168884868762caaedd3382c4b557.png)
OpenGL空间(坐标系)变换⽹友的《3D图形学的学习策略》⼀⽂使我深受启发,在图形学以及openGL学习⽅⾯给了我很有价值的指导性意见,在此对前辈们的不吝赐教表⽰感激,谢谢你们的⽆私分享。
如⽂章所说,API是⼯具,不是本质,OpenGL/Direct3D的本质是图形学,⽽不是OpenGL/Direct3D的本⾝,API的本⾝只是⼀些Interface⽽已。
最重要的,最根本的是,你要明⽩这些API背后的图形学的原理---因为那才是根本中的根本。
其实很多事情,包括学习也涉及到⽣活,只有抓住了本质,才能体会到其中的真谛。
带着这种希望探究本质的学习⽅法,结合图形学原理,通过阅读书⽬和⽹友们的⽂章,我对OpenGL⼏何空间变换进⾏了总结性的学习。
OpenGL处理管线的⽬的是将对象的三维描述转换为可以显⽰的⼆维图像。
为了完成这个从三维到⼆维的转换,OpenGL 使⽤了多个空间(坐标系),每个空间完成特定的任务,从⼀个空间到另⼀个空间需要进⾏空间转换。
理解OpenGL所使⽤的各种空间以及它们间的变换是⾮常重要的。
如上图所⽰,openGL中使⽤的空间依次是:对象空间、世界空间、视点空间、裁剪空间、归⼀化设备空间、窗⼝空间、屏幕空间。
结合⾃⼰的理解,就每个空间完成的基本任务和空间的变换关系,总结如下。
对象空间。
对象空间中完成的最⼤任务是对象建模,三维对象的属性,包括顶点位置和表⾯法线等是在这个空间内指定的。
这个空间的坐标原点⼀般在对象上,有时候也在其他地⽅,主要是为了建模⽅便。
每⼀个对象都有⼀个⾃⼰的对象空间。
就openGL⽽⾔,我⽬前还没有接触到建⽴很复杂模型的应⽤,建模⼀般在其他地⽅如3DMAX中完成,然后读⼊openGL进⾏处理。
世界空间。
对象空间之后是世界空间,我理解为世界坐标系是固定不变的。
世界空间主要是对三维场景进⾏描述,就是把已经建⽴的各种对象摆放在三维空间中,空间的转换是通过模型变换完成的。
可以通过平移、旋转、⽐例缩放等把对象摆放在需要的位置,就好像买好家具以后设计房间布局⼀样。
OpenGL入门学习——第五课 三维的空间变换分析
![OpenGL入门学习——第五课 三维的空间变换分析](https://img.taocdn.com/s3/m/c41582f5551810a6f524863e.png)
OpenGL入门学习——第五课三维的空间变换今天要讲的是三维变换的内容,课程比较枯燥。
主要是因为很多函数在单独使用时都不好描述其效果,我只好在最后举一个比较综合的例子。
希望大家能一口气看到底了。
只看一次可能不够,如果感觉到迷糊,不妨多看两遍。
有疑问可以在下面跟帖提出。
我也使用了若干图形,希望可以帮助理解。
在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能是X轴向右,Y轴向上,Z轴垂直屏幕。
这些限制给我们的绘图带来了很多不便。
我们生活在一个三维的世界——如果要观察一个物体,我们可以:1、从不同的位置去观察它。
(视图变换)2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。
(模型变换)3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。
另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。
(投影变换)4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。
(视口变换)这些,都可以在OpenGL中实现。
OpenGL变换实际上是通过矩阵乘法来实现。
无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。
关于矩阵的知识,这里不详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。
OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。
这里就不做介绍了。
1、模型变换和视图变换从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。
在OpenGL中,实现这两种功能甚至使用的是同样的函数。
由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。
设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:glMatrixMode(GL_MODELVIEW);通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
OpenGL第五课 中文
![OpenGL第五课 中文](https://img.taocdn.com/s3/m/91723d2fed630b1c59eeb59e.png)
第五课中文3D空间:我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体。
在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D世界中的2D对象。
我们给三角形增加一个左侧面,一个右侧面,一个后侧面来生成一个金字塔(四棱锥)。
给正方形增加左、右、上、下及背面生成一个立方体。
我们混合金字塔上的颜色,创建一个平滑着色的对象。
给立方体的每一面则来个不同的颜色。
int DrawGLScene(GLvoid) // 此过程中包括所有的绘制代码{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存glLoadIdentity(); // 重置模型观察矩阵glTranslatef(-1.5f,0.0f,-6.0f); // 左移1.5 单位,并移入屏幕6.0glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转金字塔glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面有些人可能早已在上节课中的代码上尝试自行创建3D对象了。
但经常有人来信问我:"我的对象怎么不会绕着其自身的轴旋转?看起来总是在满屏乱转。
"要让您的对象绕自身的轴旋转,您必须让对象的中心坐标总是(0.0f,0,0f,0,0f)。
下面的代码创建一个绕者其中心轴旋转的金字塔。
金字塔的上顶点高出原点一个单位,底面中心低于原点一个单位。
上顶点在底面的投影位于底面的中心。
注意所有的面-三角形都是逆时针次序绘制的。
这点十分重要,在以后的课程中我会作出解释。
现在,您只需明白要么都逆时针,要么都顺时针,但永远不要将两种次序混在一起,除非您有足够的理由必须这么做。
我们开始画金字塔的前侧面。
因为所有的面都共享上顶点,我们将这点在所有的三角形中都设置为红色。
图形学实验报告 OpenGL中的变换
![图形学实验报告 OpenGL中的变换](https://img.taocdn.com/s3/m/c8d35f07bb68a98271fefa38.png)
《计算机图形学基础》实验6 OpenGL中的变换一、实验目的及要求1.理解OpenGL中的各种变换的实现原理;2.掌握OpenGL中模型视图矩阵的操作方法。
3.掌握OpenGL中投影变换的实现方法。
二、实验环境主要是软件开发环境VC 6.0三、实验内容1、分子动画示例2、深度测试示例四、实验结果1、分子动画五、程序代码1.分子动画#include <gl/glut.h>void Initial(){glEnable(GL_DEPTH_TEST); // 启用深度测试glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); //背景为白色}void ChangeSize(int w, int h){if(h == 0) h = 1;glViewport(0, 0, w, h); // 设置视区尺寸glMatrixMode(GL_PROJECTION); // 指定当前操作投影矩阵堆栈glLoadIdentity(); // 重置投影矩阵GLfloat fAspect;fAspect = (float)w/(float)h; // 计算视区的宽高比gluPerspective(45.0, fAspect, 1.0, 500.0); // 指定透视投影的观察空间glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void Display(void){static float fElect1 = 0.0f; // 绕原子旋转的角度glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓冲区glMatrixMode(GL_MODELVIEW); // 指定当前操作模型视图矩阵堆栈glLoadIdentity(); // 重置模型视图矩阵glTranslatef(0.0f, 0.0f, -250.0f); //将图形沿z轴负向移动glColor3f(1.0f, 0.0f, 0.0f);glutSolidSphere(12.0f, 15, 15); // 绘制红色的原子glColor3f(0.0f, 0.0f, 0.0f);glPushMatrix(); // 保存当前的模型视图矩阵glRotatef(fElect1, 0.0f, 1.0f, 0.0f); // 绕y轴旋转一定的角度glTranslatef(90.0f, 0.0f, 0.0f); // 平移一段距离glutSolidSphere(6.0f, 15, 15); // 画出第一个电子glPopMatrix(); // 恢复模型视图矩阵glPushMatrix(); // 保存当前的模型视图矩阵glRotatef(45.0f, 0.0f, 0.0f, 1.0f); //绕z轴旋转45°glRotatef(fElect1, 0.0f, 1.0f, 0.0f);glTranslatef(-70.0f, 0.0f, 0.0f);glutSolidSphere(6.0f, 15, 15); // 画出第二个电子glPopMatrix(); // 恢复模型视图矩阵glPushMatrix(); // 保存当前的模型视图矩阵glRotatef(-45.0f,0.0f, 0.0f, 1.0f); //绕z轴旋转-45°glRotatef(fElect1, 0.0f, 1.0f, 0.0f);glTranslatef(0.0f, 0.0f, 60.0f);glutSolidSphere(6.0f, 15, 15); // 画出第三个电子glPopMatrix();fElect1 += 10.0f; // 增加旋转步长,产生动画效果if(fElect1 > 360.0f) fElect1 = 10.0f;glutSwapBuffers();}void TimerFunc(int value){glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutCreateWindow("分子动画示例");glutReshapeFunc(ChangeSize);glutDisplayFunc(Display);glutTimerFunc(500, TimerFunc, 1); //指定定时器回调函数Initial();glutMainLoop();return 0;}六、心得体会这次的分子动画实验比较有意思,就是对代码的理解性不是很高。
OpenGL图形变换
![OpenGL图形变换](https://img.taocdn.com/s3/m/9760303767ec102de2bd893b.png)
OpenGL图形变换OpenGL图形软件包是为三维应用设计的,其中包含了大量的有关三维变换的操作,二维变换则可以看作是三维变换的特例。
OpenGL中常用的变换包括模型视图变换、投影变换和视见区变换。
一、矩阵堆栈在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将三维形体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到了变换后的形体顶点的齐次坐标矩阵,这样只要求出形体的三维变换矩阵,就可以得到变换后的形体。
在OpenGL中,对象的坐标变换也是通过矩阵来实现的。
OpenGL中包含了两个重要的矩阵:模型视图矩阵和投影矩阵,其中模型视图矩阵用于物体的模型视图变换,投影矩阵用于投影变换。
一般来说,在进行矩阵操作之前,需要指定当前操作的矩阵对象,这可以使用函数:glMatrixMode(GLenum mode);定义。
其中当mode取GL_MODELVIEW时,表示对模型视图矩阵进行操作;当mode取GL_PROJECTION时表示对投影矩阵进行操作,并且一旦设置了当前操作矩阵,它就将保持为当前的矩阵对象,直到再次调用函数glMatrixMode修改它为止。
默认情况下,系统处理的当前矩阵是模型视图矩阵。
OpenGL为模型视图矩阵和投影矩阵各维护着一个“矩阵堆栈”,其中堆栈的栈顶矩阵就是当前的模型视图矩阵或投影矩阵。
在调用变换函数的时候,系统自动计算变换函数对应的变换矩阵与当前操作的矩阵堆栈栈顶矩阵的乘积,并置为栈顶矩阵,绘制图形时使用栈顶矩阵作为图形的变换矩阵。
矩阵堆栈主要用来保存和恢复矩阵的状态。
OpenGL中利用函数:void glPushMatrix(void);void glPopMatrix(void);实现矩阵堆栈的操作。
其中函数glPushMatrix将当前矩阵堆栈的栈顶矩阵复制一个,并将其压入当前矩阵堆栈,以保存当前变换矩阵。
函数glPopMatrix用于将当前矩阵堆栈的栈顶矩阵弹出,这样,堆栈中的下一个矩阵变为栈顶矩阵(当前变换矩阵),用来恢复当前变换矩阵原先的状态。
3D编程基础知识(opengl)
![3D编程基础知识(opengl)](https://img.taocdn.com/s3/m/9fe05f8ccc22bcd126ff0c08.png)
3D编程基础知识(OpenGL)一、前言科学计算可视化、计算机动画、虚拟现实是计算机图形学领域内三大活跃的发展方向,它们的技术核心都是三维真实感图形。
而OpenGL就是这三维真实感图形的构造之一。
二、概述1、Direct3D & OpenGLDirect3D是Microsoft的DirectX其中的一个COM组件,目前最新版本是Direct9.0c;OpenGL最初由SGI开发,目前由OpenGL体系结构审核委员会(ARB)所维护。
OpenGL ARB 是个行业协会,负责OpenGL以及相关技术的发展和演变。
OpenGL ARB由下面这些计算机图形行业的领先企业所组成:3Dlabs、Apple、ATI、Dell、IBM、Intel、NVIDIA、SGI和Sun Microsystems。
最新的规范是2.0。
有两套实现,一套是SGI的OpenGL实现,一套是Microsoft 的OpenGL实现。
目前Microsoft的OpenGL只支持1.1规范。
Direct3D:1、适合做游戏开发。
DirectX是非常成熟的游戏开发的组件,辅助的功能库、数学库都很强大和成熟,如D3DX.lib中包含的大量辅助函数,而OpenGL没有这些相关的东西,它只专注于3d的渲染,辅助的东西不得不由第三方提供,或者自己开发...而且DirectX更新比较快。
2、Direct3D是面向对象的COM实现。
OpenGL只是一套面向结构的图形API。
3、OpenGL不支持一些低端显卡。
OpenGL:1、跨平台性。
可应用在Windows、OS/2、Unix、Max等系统上。
2、在光源和纹理的处理上性能比较优秀。
2、OpenGL的发展OpenGL(Open Graphics Library),开放图形程序接口。
1、1992年7月,SGI公司发布OpenGL1.0。
2、1995年,SGI发布OpenGL1.1 。
3、2001年8月,ARB发布OpenGL1.3规范。
OpenGL图形编程3二维观察与三维变换ppt课件
![OpenGL图形编程3二维观察与三维变换ppt课件](https://img.taocdn.com/s3/m/bc97f18a482fb4daa48d4b73.png)
ppt课件.
1
3.1二维观察 3.2三维变换
3. OpenGL二维观察与三维变换
ppt课件.
2
3. 1OpenGL二维观察
实现二维观察的步骤: 3.1.1指定矩阵堆栈 3.1.2指定裁剪窗口 3.1.3指定视区
ppt课件.
33
3.1.1指定矩阵堆栈
指定当前操作的是投影矩阵堆栈
当角度参数是 0.0 时,表示对物体没有影响。
ppt课件.
22 22
3.2.2模型视图矩阵
比例
void glScale{fd}(TYPE x,TYPE y,TYPE z);
三个参数值就是目标分别沿三个轴向缩放的比例因子。这个函数用这三个 比例因子生成的矩阵完成乘法。
这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。 当参数是(1.0,1.0,1.0)时,对物体没有影响。 当其中某个参数为负值时,表示将对目标进行相应轴的反射变换,且这个
ppt课件.
12 12
3.2.1变换种类
投影变换:对视见空间进行修剪和改变大小; 投影变换应用到最终的模型视图方向。投影实际
上定义了视见空间并建立了修剪平面。更明确 一些,投影变换指定已完成场景如何转换成屏 幕上的最终图象。常用的投影变换包括 正投 影和透视投影。
ppt课件.
13 13
3.2.1变换种类
在OpenGL中,对象的坐标变换也通过矩阵来实现的(虽然并不一 定要自己定义矩阵)。通常,在OpenGL中使用了两个重要的矩 阵:模型视图矩阵和投影矩阵,其中模型视图矩阵用于物体的模 型视图变换,投影矩阵用于投影变换。
ppt课件.
15 15
3.2.1变换种类
opengl算法学习---图形几何变换
![opengl算法学习---图形几何变换](https://img.taocdn.com/s3/m/7dddf62a86c24028915f804d2b160b4e767f8139.png)
opengl算法学习---图形⼏何变换图形⼏何变换图形变换是计算机图形学中的⼀个重要内容。
通过对简单图形进⾏多种变换和组合,可以形成⼀个复杂图形,这些操作也⽤于将世界坐标系中的场景描述转换为输出设备上的观察显⽰中。
应⽤于对象⼏何描述并改变它的位置、⽅向或⼤⼩等⼏何信息的操作称为⼏何变换(Geometric Transformation)。
这种变换⼀般维持图形的拓扑关系(构成规则)不变,只改变图形的⼏何关系(⼤⼩、形状及相对位置),主要包括平移、放缩、旋转及投影等操作。
平移变换\[P=\begin{bmatrix} x \\ y \end{bmatrix} {P}'=\begin{bmatrix} {x}' \\ {y}' \end{bmatrix} T=\begin{bmatrix} t_{x} \\ t_{y} \end{bmatrix}\]\[{P}'=P+T \]通过齐次坐标变换矩阵表⽰\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix}1 & 0 & t_{x}\\ 0 & 1 & t_{y} \\ 0 & 0& 1 \end{bmatrix}\cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix}= T(t_{x},t_{y})\cdot P \]绕坐标原点的旋转变换旋转⾓定向:逆时针为正,顺时针为负\[cos(\alpha + \theta )= cos(\alpha)cos(\theta) - sin(\alpha)sin(\theta) \]\[sin(\alpha + \theta )= sin(\alpha)cos(\theta) + cos(\alpha)sin(\theta) \]\[OA=\begin{bmatrix} rcos(\alpha) \\ rsin(\alpha) \end{bmatrix} OB=\begin{bmatrix} rcos(\alpha + \theta ) \\ rsin(\alpha + \theta ) \end{bmatrix} T=\begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}\]\[OB=OA \cdot T \]通过齐次坐标变换矩阵表⽰\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix}cos \theta & -sin \theta & 0\\ sin \theta & cos \theta & 0 \\ 0 & 0& 1\end{bmatrix}\cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix}= R(\theta) \cdot P \]以坐标原点为基准点的缩放变换\[{x}'=x \cdot s_{x} \]\[{y}'=y \cdot s_{y} \]\[{P}'=\begin{bmatrix}{x}'\\ {y}' \end{bmatrix} =\begin{bmatrix}s_{x} & 0\\ 0 & s_{y} \end{bmatrix}\cdot\begin{bmatrix}x\\ y \end{bmatrix}= s \cdot P\]通过齐次坐标变换矩阵表⽰\[{x}'=x \cdot s_{x} \]\[{y}'=y \cdot s_{y} \]\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} s_{x} & 0 & 0\\ 0 & s_{y} & 0 \\ 0 & 0& 1 \end{bmatrix}\cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix}= S(S_{x},s_{y}) \cdot P \]反射变换产⽣对象镜像的变换称为反射(reflection),变换通过将对象绕反射轴旋转180°来⽣成反射镜像1 相对于x轴的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix} =\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]2 相对于y轴的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]3 相对于坐标原点的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} -1 & 0 \\ 0 & -1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]通过齐次坐标变换矩阵表⽰\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} a & b & 0\\ c & d & 0 \\ 0 & 0& 1 \end{bmatrix} \cdot \begin{bmatrix}x\\ y \\ 1 \end{bmatrix} =R(a,b,c,d) \cdot P \]4 相对于任意点的反射\[{P}'=\begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} -1 & 0 & 2u\\ 0 & -1 & 2v \\ 0 & 0& 1 \end{bmatrix} \cdot \begin{bmatrix}x\\ y \\ 1 \end{bmatrix} =T \cdot P \]5 关于对⾓线 y= x 的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]6 关于对⾓线 y= -x 的反射\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix}= \begin{bmatrix} 0 & -1 \\ -1 & 0 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]7 相对于任意直线 y=mx+b 的反射\[p'= \begin{bmatrix} x'\\ y' \\ 1 \end{bmatrix} = \frac{1}{1+m^{2}} \begin{bmatrix} 1-m^{2} & 2m & -2mb\\ 2m & m^{2}-1 & 2b\\ 0 & 0 & 1+m^{2} \end{bmatrix} \cdot \begin{bmatrix} x\\ y \\ 1 \end{bmatrix} =T\cdot P \]错切变换错切(shear)是⼀种使对象形状发⽣变化的变换,经过错切的对象好像是由相互滑动的内部夹层组成相对于x轴的x⽅向错切由下列变换产⽣\[ \begin{bmatrix} {x}' \\ {y}' \end{bmatrix} =\begin{bmatrix} 1 & sh_{x} \\ 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} \]该变换对应的坐标转换为\[{x}'=x+sh_{x} \cdot y \]\[{y}'=y \]通过齐次坐标变换矩阵表⽰相对于线\(y=y_{ref}\)的x⽅向错切\[ \begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} 1 & sh_{x} & -sh_{x} \cdot y_{ref} \\ 0 & 1 & 0 \\ 0 & 0& 1 \end{bmatrix} \cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix} \]相对于线\(x=x_{ref}\)的y⽅向错切\[ \begin{bmatrix}{x}'\\ {y}' \\ 1 \end{bmatrix} =\begin{bmatrix} 1 & 0 & 0 \\ sh_{y} & 1 & -sh_{y} \cdot x_{ref}\\ 0 & 0& 1 \end{bmatrix} \cdot\begin{bmatrix}x\\ y \\ 1 \end{bmatrix} \]逆变换通过齐次坐标变换矩阵表⽰平移逆变换\[T^{-1} =\begin{bmatrix} 1 & 0 & -t_{x} \\ 0 & 1 & -t_{y} \\ 0 & 0& 1 \end{bmatrix} \]旋转逆变换\[R^{-1} =\begin{bmatrix} cos \theta & -sin \theta & 0 \\ sin \theta & cos \theta & 0 \\ 0 & 0& 1 \end{bmatrix} \]缩放逆变换\[S^{-1} =\begin{bmatrix} \frac{1}{s_{x}} & 0 & 0 \\ 0 & \frac{1}{s_{y}} & 0 \\ 0 & 0& 1 \end{bmatrix} \]⼆维复合变换利⽤矩阵表达式,可以通过计算单个变换的矩阵乘积,将任意的变换序列组成复合变换矩阵。
三维空间旋转变换公式
![三维空间旋转变换公式](https://img.taocdn.com/s3/m/7c62a99277a20029bd64783e0912a21615797f72.png)
三维空间旋转变换公式在三维空间中,旋转变换是一种常见的操作,它允许我们将物体绕指定的轴进行旋转。
为了实现这一操作,我们需要使用旋转变换公式。
下面是三维空间旋转变换公式的描述。
在三维空间中,旋转变换可以由旋转矩阵来表示。
对于一个给定的点P(x, y, z),通过旋转变换,我们可以得到旋转后的点P'(x', y', z')。
旋转变换公式如下:x' = cosθ * (cosβ * cosγ) * x + (cosθ * sinβ * cosγ - sinθ * sinγ) * y + (cosθ * sinβ * sinγ + sinθ * cosγ) * zy' = sinθ * (cosβ * cosγ) * x + (sinθ * sinβ * cosγ + cosθ * sinγ) * y + (sinθ * sinβ * sinγ - cosθ * cosγ) * zz' = -sinβ * cosγ * x + sinβ * sinγ * y + cosβ * z其中,θ表示绕x轴的旋转角度,β表示绕y轴的旋转角度,γ表示绕z轴的旋转角度。
通过这个公式,我们可以将三维空间中的点进行绕任意轴的旋转。
根据旋转矩阵的性质,我们可以将多个旋转进行组合,以实现复杂的旋转效果。
需要注意的是,旋转角度值使用弧度制表示。
若需要使用角度制,需要进行相应的转换。
总结起来,三维空间旋转变换公式允许我们通过旋转矩阵将一个给定的点绕指定的轴进行旋转。
这个公式给出了旋转后的点在三维坐标系中的新坐标。
通过合理使用旋转角度,我们可以实现在三维空间中的各种旋转变换。
opengl坐标变换.ppt
![opengl坐标变换.ppt](https://img.taocdn.com/s3/m/f10c580cbcd126fff7050bb4.png)
2019/3/19
计算机图形学
5
3、模型变换
模型变换是让你去定位和定向一个模型,移动旋转以及缩放它。 在模型变换中指定次序是非常重要的,因为它们会影响到场景的 最终结果。
y y1 y x1 x x y1 y x1
x
2019/3/19
计算机图形学
6
y
y
y1 x1 x
y y1 x1 x
x
4、模型视图的对偶性
描述:根据眼睛的位置、场景中心的位置和从观察者的角度 往上指的矢量,定义一个视图变换。
2019/3/19
计算机图形学
13
2019/3/19
计算机图形学
4
(1)将视图矩阵设置为单位矩阵相同。它将使“摄像机”恢复为默认位 置和方向,即位于原点并朝向z的负轴。 (2)使用gluLookAt( )功能函数指定一条从“摄像机”伸延出来的视线。 (3)使用平移和旋转命令glTranslate( )和glRotate( )。使用它们将世界 中的物体相对于固定的“摄像机”进行移动。 (4)使用平移和旋转功能函数为你自己的坐标系统创建函数。
OpenGL坐标变换
一、了解OpenGL中的变换
变换使得把3D坐标投影到2D场景成为可能。变换还使你能 够旋转对象、移动对象,甚至拉伸、压缩和弯曲它们。和直接 修改对象不同,在我们计算机的实现中,实际上是将物件的局 部坐标系统变换成另外的坐标系统。
变换 视图 模型 用途 指定观察者或摄影机的位置 在场景中移动对象
2019/3/19
计算机图形学
11
(2)透视投影矩阵 实现函数: void glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); void gluPerspective (GLdouble fov, GLdouble aspect, GLdouble near, GLdouble far);
三维空间的投影变换——点,平面,直线,二次曲面
![三维空间的投影变换——点,平面,直线,二次曲面](https://img.taocdn.com/s3/m/c39d85e24793daef5ef7ba0d4a7302768e996f19.png)
三维空间的投影变换——点,平⾯,直线,⼆次曲⾯1. 三维空间中的点在三维空间P3中的⼀点(X, Y, Z)T,它的齐次坐标为4元向量(X1,X2,X3,X4)T,可归⼀化表⽰为((X, Y, Z, 1)T,若X4 = 0,则表⽰该点位于⽆限远处。
对三维空间P3上的点的投影变换,通过对齐次向量X左乘⼀个4x4⾮奇异矩阵H得到,即X' = HX. 其中变换矩阵H有15个⾃由度,外加⼀个任意⽐例因⼦。
2. 三维空间中的平⾯与⼆维空间中直线的表⽰⽅法相似,三维空间中的平⾯可以⽤如下⽅程表⽰为π1X +π2Y +π3Z +π4 = 0因此平⾯的齐次表⽰为π = (π1,π2,π3,π4)T,它有3个⾃由度。
上式可简写为πT X = 0这表⽰点 X = (X, Y, Z, 1)T 位于平⾯π上。
3. 平⾯的性质三点决定⼀个平⾯。
设有3个线性独⽴的点X i, for i = 1,2, 3, 它们均位于⼀个平⾯π上,即满⾜πT X i = 0。
进⾏矩阵堆叠得到于是平⾯π是这个3x4矩阵的零空间向量,可在任意⽐例尺度上,被唯⼀确定。
在平⾯空间P2中,两点决定⼀条直线,直线l 除了可以⽤零空间向量法求解之外,还可以通过两个齐次点的叉积 l = x × y 直接求得。
在三维空间P3中,也可以⽤类似叉积的⽅法求解平⾯。
三个平⾯决定⼀点。
设有3个线性独⽴的平⾯πi, for i = 1,2, 3, 则它们的交点X可以由下式求得点X 是这个3x4矩阵的零空间向量。
这是平⾯空间P2中两线交于⼀点在三维空间P3中的推⼴。
投影变换。
在点变换 X' = HX 下,平⾯的变换表⽰为:π' =H-Tπ参数化。
在平⾯π上的⼀点X可以写成X = Mx其中4x3矩阵M的各列是πT的零空间,即πT M = 0。
⽽3元向量 x 表⽰X在⼆维空间P2上的投影,是对点X的参数化。
4. 三维空间中的直线直线可以定义为两个点的连线,或两个平⾯的相交。
Open3d学习计划(3)变换
![Open3d学习计划(3)变换](https://img.taocdn.com/s3/m/b22bc6d39fc3d5bbfd0a79563c1ec5da50e2d612.png)
Open3d学习计划(3)变换Open3D是⼀个开源库,⽀持快速开发和处理3D数据。
Open3D在c++和Python中公开了⼀组精⼼选择的数据结构和算法。
后端是⾼度优化的,并且是为并⾏化⽽设置的。
本系列学习计划有Blue同学作为发起⼈,主要以Open3D官⽅⽹站的教程为主进⾏翻译与实践的学习计划。
点云PCL公众号作为免费的3D视觉,点云交流社区,期待有使⽤Open3D或者感兴趣的⼩伙伴能够加⼊我们的翻译计划,贡献免费交流社区,为使⽤Open3D提供中⽂的使⽤教程。
变换(transform)Open3d的⼏何类型有许多变化⽅法。
在本节教程中我们将会展⽰如何使⽤旋转(rotate),平移(translate),缩放(scale)和变换(transform)。
平移(translate)这⾥我们展⽰的第⼀个算法是平移。
平移算法就是通过单个三维向量 ttt 来平移所有点/顶点,vt=v+tv_{t} = v + tvt=v+t。
下⾯的代码展⽰了⽹格分别在x⽅向和y⽅向平移⼀次的结果。
mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()mesh_tx =copy.deepcopy(mesh).translate((1.3,0,0))mesh_ty = copy.deepcopy(mesh).translate((0,1.3,0))print(f'Center of mesh: {mesh.get_center()}')print(f'Center of mesh tx: {mesh_tx.get_center()}')print(f'Center of mesh ty: {mesh_ty.get_center()}')o3d.visualization.draw_geometries([mesh, mesh_tx, mesh_ty])Center of mesh: [0.05167549 0.05167549 0.05167549]Center of mesh tx: [1.35167549 0.05167549 0.05167549]Center of mesh ty: [0.05167549 1.35167549 0.05167549]Note:get_center算法返回的是三⾓⽹格顶点的平均值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
OpenGL入门学习——第五课三维的空间变换今天要讲的是三维变换的内容,课程比较枯燥。
主要是因为很多函数在单独使用时都不好描述其效果,我只好在最后举一个比较综合的例子。
希望大家能一口气看到底了。
只看一次可能不够,如果感觉到迷糊,不妨多看两遍。
有疑问可以在下面跟帖提出。
我也使用了若干图形,希望可以帮助理解。
在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能是X轴向右,Y轴向上,Z轴垂直屏幕。
这些限制给我们的绘图带来了很多不便。
我们生活在一个三维的世界——如果要观察一个物体,我们可以:1、从不同的位置去观察它。
(视图变换)2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。
(模型变换)3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。
另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。
(投影变换)4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。
(视口变换)这些,都可以在OpenGL中实现。
OpenGL变换实际上是通过矩阵乘法来实现。
无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。
关于矩阵的知识,这里不详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。
OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。
这里就不做介绍了。
1、模型变换和视图变换从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。
在OpenGL中,实现这两种功能甚至使用的是同样的函数。
由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。
设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:glMatrixMode(GL_MODELVIEW);通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
这也只需要一行代码:glLoadIdentity();然后,就可以进行模型变换和视图变换了。
进行模型和视图变换,主要涉及到三个函数:glTranslate*,把当前矩阵和一个表示移动物体的矩阵相乘。
三个参数分别表示了在三个坐标上的位移值。
glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。
物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。
glScale*,把当前矩阵和一个表示缩放物体的矩阵相乘。
x,y,z分别表示在该方向上的缩放比例。
注意我都是说“与XX相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。
假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。
所以,经过变换得到的顶点坐标就是((RT)v)。
由于矩阵乘法的结合率,((RT)v) = (R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。
即:实际变换的顺序与代码中写的顺序是相反的。
由于“先移动后旋转”和“先旋转后移动”得到的结果很可能不同,初学的时候需要特别注意这一点。
OpenGL之所以这样设计,是为了得到更高的效率。
但在绘制复杂的三维图形时,如果每次都去考虑如何把变换倒过来,也是很痛苦的事情。
这里介绍另一种思路,可以让代码看起来更自然(写出的代码其实完全一样,只是考虑问题时用的方法不同了)。
让我们想象,坐标并不是固定不变的。
旋转的时候,坐标系统随着物体旋转。
移动的时候,坐标系统随着物体移动。
如此一来,就不需要考虑代码的顺序反转的问题了。
以上都是针对改变物体的位置和方向来介绍的。
如果要改变观察点的位置,除了配合使用glRotate*和glTranslate*函数以外,还可以使用这个函数:gluLookAt。
它的参数比较多,前三个参数表示了观察点的位置,中间三个参数表示了观察目标的位置,最后三个参数代表从(0,0,0)到(x,y,z)的直线,它表示了观察者认为的“上”方向。
2、投影变换投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上。
(注意,从现在起,坐标可以不再是-1.0到1.0了!)OpenGL支持两种类型的投影变换,即透视投影和正投影。
投影也是使用矩阵来实现的。
如果需要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。
glMatrixMode(GL_PROJECTION);通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
glLoadIdentity();透视投影所产生的结果类似于照片,有近大远小的效果,比如在火车头内向前照一个铁轨的照片,两条铁轨似乎在远处相交了。
使用glFrustum函数可以将当前的可视空间设置为透视投影空间。
其参数的意义如下图:声明:该图片来自,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。
也可以使用更常用的gluPerspective函数。
其参数的意义如下图:声明:该图片来自,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。
正投影相当于在无限远处观察得到的结果,它只是一种理想状态。
但对于计算机来说,使用正投影有可能获得更好的运行速度。
使用glOrtho函数可以将当前的可视空间设置为正投影空间。
其参数的意义如下图:声明:该图片来自,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。
如果绘制的图形空间本身就是二维的,可以使用gluOrtho2D。
他的使用类似于glOrgho。
3、视口变换当一切工作已经就绪,只需要把像素绘制到屏幕上了。
这时候还剩最后一个问题:应该把像素绘制到窗口的哪个区域呢?通常情况下,默认是完整的填充整个窗口,但我们完全可以只填充一半。
(即:把整个图象填充到一半的窗口内)声明:该图片来自,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。
使用glViewport来定义视口。
其中前两个参数定义了视口的左下脚(0,0表示最左下方),后两个参数分别是宽度和高度。
4、操作矩阵堆栈介于是入门教程,先简单介绍一下堆栈。
你可以把堆栈想象成一叠盘子。
开始的时候一个盘子也没有,你可以一个一个往上放,也可以一个一个取下来。
每次取下的,都是最后一次被放上去的盘子。
通常,在计算机实现堆栈时,堆栈的容量是有限的,如果盘子过多,就会出错。
当然,如果没有盘子了,再要求取一个盘子,也会出错。
我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。
当我们需要保存时,调用glPushMatrix函数,它相当于把矩阵(相当于盘子)放到堆栈上。
当需要恢复最近一次的保存时,调用glPopMatrix函数,它相当于把矩阵从堆栈上取下。
OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。
因此不必过于担心矩阵的容量问题。
通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。
注意:模型视图矩阵和投影矩阵都有相应的堆栈。
使用glMatrixMode 来指定当前操作的究竟是模型视图矩阵还是投影矩阵。
5、综合举例好了,视图变换的入门知识差不多就讲完了。
但我们不能就这样结束。
因为本次课程的内容实在过于枯燥,如果分别举例,可能效果不佳。
我只好综合的讲一个例子,算是给大家一个参考。
至于实际的掌握,还要靠大家自己花功夫。
闲话少说,现在进入正题。
我们要制作的是一个三维场景,包括了太阳、地球和月亮。
假定一年有12个月,每个月30天。
每年,地球绕着太阳转一圈。
每个月,月亮围着地球转一圈。
即一年有360天。
现在给出日期的编号(0~359),要求绘制出太阳、地球、月亮的相对位置示意图。
(这是为了编程方便才这样设计的。
如果需要制作更现实的情况,那也只是一些数值处理而已,与OpenGL关系不大)首先,让我们认定这三个天体都是球形,且他们的运动轨迹处于同一水平面,建立以下坐标系:太阳的中心为原点,天体轨迹所在的平面表示了X轴与Y轴决定的平面,且每年第一天,地球在X轴正方向上,月亮在地球的正X轴方向。
下一步是确立可视空间。
注意:太阳的半径要比太阳到地球的距离短得多。
如果我们直接使用天文观测得到的长度比例,则当整个窗口表示地球轨道大小时,太阳的大小将被忽略。
因此,我们只能成倍的放大几个天体的半径,以适应我们观察的需要。
(百度一下,得到太阳、地球、月亮的大致半径分别是:696000km, 6378km,1738km。
地球到太阳的距离约为1.5亿km=150000000km,月亮到地球的距离约为380000km。
)让我们假想一些数据,将三个天体的半径分别“修改”为:69600000(放大100倍),15945000(放大2500倍),4345000(放大5000倍)。
将地球到月亮的距离“修改”为38000000(放大100倍)。
地球到太阳的距离保持不变。
为了让地球和月亮在离我们很近时,我们仍然不需要变换观察点和观察方向就可以观察它们,我们把观察点放在这个位置:(0, -200000000, 0) ——因为地球轨道半径为150000000,咱们就凑个整,取-200000000就可以了。
观察目标设置为原点(即太阳中心),选择Z轴正方向作为“上”方。
当然我们还可以把观察点往“上”方移动一些,得到(0, -200000000, 200000000),这样可以得到45度角的俯视效果。
为了得到透视效果,我们使用gluPerspective来设置可视空间。
假定可视角为60度(如果调试时发现该角度不合适,可修改之。
我在最后选择的数值是75。
),高宽比为1.0。
最近可视距离为1.0,最远可视距离为200000000*2=400000000。
即:gluPerspective (60, 1, 1, 400000000);现在我们来看看如何绘制这三个天体。
为了简单起见,我们把三个天体都想象成规则的球体。
而我们所使用的glut实用工具中,正好就有一个绘制球体的现成函数:glutSolidSphere,这个函数在“原点”绘制出一个球体。
由于坐标是可以通过glTranslate*和glRotate*两个函数进行随意变换的,所以我们就可以在任意位置绘制球体了。
函数有三个参数:第一个参数表示球体的半径,后两个参数代表了“面”的数目,简单点说就是球体的精确程度,数值越大越精确,当然代价就是速度越缓慢。