第6章 图形几何变换.

Slides:



Advertisements
Similar presentations
2.8 函数的微分 1 微分的定义 2 微分的几何意义 3 微分公式与微分运算法则 4 微分在近似计算中的应用.
Advertisements

§3.4 空间直线的方程.
第七章 空间解析几何与向量代数 用代数的方法研究几何问题称为解析几何 平面解析几何 一元微积分 空间解析几何 多元微积分 本章的主要内容 :
第七章 向量代数与空间解析几何 第一节 空间直角坐标系与向量的概念 第二节 向量的坐标表示 第三节 向量的数量积和向量积 第四节 平面方程
《解析几何》 -Chapter 3 §7 空间两直线的相关位置.
第五章 二次型 §5.1 二次型的矩阵表示 §5.2 标准形 §5.3 唯一性 §5.4 正定二次型 章小结与习题.
第五章 二次型. 第五章 二次型 知识点1---二次型及其矩阵表示 二次型的基本概念 1. 线性变换与合同矩阵 2.
§1 二阶与三阶行列式 ★二元线性方程组与二阶行列式 ★三阶行列式
一、二阶行列式的引入 用消元法解二元线性方程组. 一、二阶行列式的引入 用消元法解二元线性方程组.
河南理工大学 计算机学院 徐文鹏 教学博客 Opengl.cnblogs.com
俄罗斯方块:注意观察游戏中用到的 数学的知识
第5章 定积分及其应用 基本要求 5.1 定积分的概念与性质 5.2 微积分基本公式 5.3 定积分的换元积分法与分部积分法
计算机图形学 《计算机图形学》 路 通 博士、教授 南京大学计算机科学与技术系课程
计算机科学与技术专业研究型课程 矩阵和线性变换 宋传鸣 辽宁师范大学计算机与信息技术学院.
计算机图形学 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 中国科学技术大学 视觉计算与可视化实验室
OpenGL常见问题.
第二章 矩阵(matrix) 第8次课.
Computer Graphics 计算机图形学基础 张 赐 Mail: CSDN博客地址:
OpenGL使用简介.
绘制圆与多边形 椭圆形 绘制椭圆形的方法是 drawOval(x ,y , width , height), 绘制实心椭圆形的方法是
Introduction to OpenGL (2)
PROGRAM 6 Earth E. Angel.
工业机器人技术基础及应用 主讲人:顾老师
双曲线的简单几何性质 杏坛中学 高二数学备课组.
第六章 二维变换及二维观察 如何对二维图形进行方向、尺寸和形状方面的变换。 如何进行二维观察。.
第七章 操作符重载 胡昊 南京大学计算机系软件所.
Chapter 9 (三维几何变换) To Discuss The Methods for Performing Geometric Transformations.
2.1.2 空间中直线与直线 之间的位置关系.
平行四边形的性质 灵寿县第二初级中学 栗 彦.
工业机器人技术基础及应用 主讲人:顾老师
变换与裁剪.
Chapter 5 Attributes of Output Primitives (图元的属性)
实数与向量的积.
线段的有关计算.
线性代数 第二章 矩阵 §1 矩阵的定义 定义:m×n个数排成的数表 3) 零矩阵: 4) n阶方阵:An=[aij]n×n
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
Module - pyopengl 應用於2d,3d圖形繪製.
OpenGL几何变换程序.
3.3 垂径定理 第2课时 垂径定理的逆定理.
§1体积求法 一、旋转体的体积 二、平行截面面积为已知的立体的体积 三、小结.
GLUT 事件處理函式 靜宜大學資管系 蔡奇偉 副教授
复习: 若A(x1,y1,z1) , B(x2,y2,z2), 则 AB = OB - OA=(x2-x1 , y2-y1 , z2-z1)
第16讲 相似矩阵与方阵的对角化 主要内容: 1.相似矩阵 2. 方阵的对角化.
§6.7 子空间的直和 一、直和的定义 二、直和的判定 三、多个子空间的直和.
O x y i j O x y i j a A(x, y) y x 5.4 平面向量的坐标运算 5.4 平面向量的坐标运算 5.4 平面向量的坐标运算 5.4 平面向量的坐标运算 5.4 平面向量的坐标运算 5.4 平面向量的坐标运算 5.4 平面向量的坐标运算.
PROGRAM 7 SQUARE E. Angel.
OpenGL 基础 计算机科学与技术系.
第七章 图 形 变 换 (一) 2019/5/7 Thank you for your time today.
OpenGL渲染管道与投影变换.
《工程制图基础》 第五讲 投影变换.
2.2矩阵的代数运算.
第15讲 特征值与特征向量的性质 主要内容:特征值与特征向量的性质.
线 性 代 数 厦门大学线性代数教学组 2019年5月12日4时19分 / 45.
平行四边形的性质 鄢陵县彭店一中 赵二歌.
第三章 空间向量与立体几何 3.1 空间向量及其运算 3.1.2空间向量的数乘运算.
高中数学必修 平面向量的基本定理.
§2 方阵的特征值与特征向量.
在发明中学习 线性代数概念引入 之四: 矩阵运算 李尚志 中国科学技术大学.
欢迎大家来到我们的课堂 §3.1.1两角差的余弦公式 广州市西关外国语学校 高一(5)班 教师:王琦.
4.6 图形的位似     观察思考:这两幅图片有什么特征? 都是有好几张相似图形组成,每个对应顶点都经过一点.
第一模块 向量代数与空间解析几何 第二节 向量及其坐标表示法 一、向量的概念 二、向量的坐标表示法.
23.6 图形与坐标 图形的变换与坐标
定义5 把矩阵 A 的行换成同序数的列得到的矩阵,
第四节 向量的乘积 一、两向量的数量积 二、两向量的向量积.
第三节 数量积 向量积 混合积 一、向量的数量积 二、向量的向量积 三、向量的混合积 四、小结 思考题.
PROGRAM 1 Simple E. Angel, Interactive Computer Graphics A Top-Down Approach with OpenGL, Third Edition Addison-Wesley Longman, 2003.
§4.5 最大公因式的矩阵求法( Ⅱ ).
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
第三章 图形的平移与旋转.
3.3.2 两点间的距离 山东省临沂第一中学.
Presentation transcript:

第6章 图形几何变换

本章目标 学习如何使图形运动 平移变换、旋转变换和放缩 学会复杂变换的分解与合成 学会使用OpenGL的几何变换函数

主要内容 数学基础 二维几何变换 齐次坐标 复合变换 其它变换 三维几何变换 图形对象的几何变换 OpenGL的几何变换函数

6.1 数学基础 矢量(vector) 连接两个点的有向线段。又称向量 行向量和列向量两种表示 矢量和

6.1 数学基础 矢量的数乘 矢量的点积 运算 性质

6.1 数学基础 矢量的长度 单位矢量 矢量间的夹角 矢量的叉积 右手法则

6.1 数学基础 矩阵(Matrix) m×n 阶矩阵 n阶方阵(m=n) 单位矩阵 n阶方阵,对角线元素为1, 其它元素为0

6.1 数学基础 矩阵(续) 行向量与列向量 矩阵的加法 当m=1时,A退化为行向量[a11, a12, …, a1n] 当n=1时, A退化为列向量[a11, a21, …, am1]T 矩阵的加法 A=(aij)m×n,B=(bij) m×n A与B的和记为A+B 性质:结合律和交换律

6.1 数学基础 矩阵(续) 矩阵的数乘 矩阵的乘法 性质:结合律和分配律(不满足交换律)

6.1 数学基础 矩阵(续) 矩阵的转置 矩阵的逆 n阶方阵A是可逆的,若存在另一个n阶方阵B,使得 AB=BA=In,称B是A的逆阵,记为B=A-1

6.2 二维几何变换 平移变换 (translation transformation) 6.2 二维几何变换 平移变换 (translation transformation) 将点P(x, y)在x轴方向、y轴方向分别平移距离tx,ty,得到点P´(x׳, y׳),则 矩阵表示: 记为:T(tx , ty)

6.2 二维几何变换 旋转变换(rotation transformation) 如 点P(x, y)的极坐标表示 6.2 二维几何变换 旋转变换(rotation transformation) 如 点P(x, y)的极坐标表示 (r为P 到原点的距离) 绕坐标原点(称为参照点,基准点)旋转角度θ (逆时针为正,顺时针为负)

6.2 二维几何变换 旋转变换(续) 记为:R(θ) 矩阵表示为:

6.2 二维几何变换 放缩变换(scaling transformation) 6.2 二维几何变换 放缩变换(scaling transformation) 将点P(x, y)在x方向, y方向分别放缩 sx 和 sy 倍,得到点P´(x׳, y׳) 以坐标原点为放缩参照(基准)点 不仅改变了物体的大小和形状,也改变了它离原点的距离 记为:S(sx, sy)

6.2 二维几何变换 利用矩阵计算变换后的坐标时,平移、旋转和放缩变换分别为: 运算不统一,如何统一运算?

6.3 齐次坐标 为什么需要齐次坐标? 计算多次不同变换时,分别利用矩阵计算各变换导致计算量大 运算表示形式不统一 平移为“+” 旋转和放缩为“·” 统一运算形式后,可以先合成变换运算的矩阵,再作用于图形对象

6.3 齐次坐标 定义 Homogeneous Coordinate (x,y)点对应的齐次坐标定义为

6.3 齐次坐标 二维变换的矩阵表示 平移变换 旋转变换

6.3 齐次坐标 放缩变换 变换具有统一表示形式的优点 便于变换合成 连续变换时,可以先得到变换的矩阵 便于硬件实现

6.3 齐次坐标 变换的性质 平移和旋转变换具有可加性 放缩变换具有可乘性

6.3 齐次坐标 逆变换 逆平移变换:正平移距离tx,ty 逆旋转变换:旋转角度为θ

6.3 齐次坐标 逆放缩变换:放缩系数为sx和sy

6.4 复合变换 变换合成 方法:连续变换时,先计算变换矩阵,再计算坐标 优点: (1)提高了对图形依次做多次变换的运算效率 如:图形上有n个顶点Pi,如果依次施加的变换为T,R,那么顶点Pi 变换后的坐标为 每个顶点需要2次矩阵相乘 只需要1次矩阵相乘

6.4 复合变换 变换合成 (续) 复合变换 (2)提供构造复杂变换的方法 Composite transformation 多个变换的组合 变换合成 (续) (2)提供构造复杂变换的方法 对图形作较复杂的变换时,不直接去计算这个变换,而是将其先分解成多个基本变换,再合成总的变换 复合变换 Composite transformation 多个变换的组合 可通过单个变换矩阵来计算矩阵乘积

6.4.1 复合平移变换 连续平移变换 平移向量为(t1x,t1y)和(t2x,t2y) 点P 经变换为P´,则有 复合矩阵

6.4.2 复合旋转变换 连续旋转 P 经连续旋转角度分别为 1 和 2 后 连续旋转具有相加性

6.4.3 复合放缩变换 连续放缩 连续放缩因子分别为:(s1x, s1y) 和 (s2x, s2y)

6.4.4 二维基准点旋转 关于任意参照点 的旋转变换 步骤:(1)平移对象使参照(基准)点移到原点(2)绕坐标原点旋转(3)平移对象使基准点回到原始位置

6.4.5 二维基准点放缩 4.3.2 扫描线算法 关于任意参照点 的放缩变换 关于任意参照点 的放缩变换 步骤:(1)平移对象使基准点与坐标原点重合(2)放缩变换(3)反向平移使得基准点回到初始位置 4.3.2 扫描线算法

6.4.6 小结 变换合成时,矩阵相乘的顺序 单次变换:列向量表示点 复合变换:先作用的放在连乘的右端,后作用的放在连 乘的左端 点表示成行向量呢?

6.5 其它变换 对称变换(反射变换、镜像变换:reflection) 关于 x 轴的对称变换 关于 y 轴的对称变换

6.5 其它变换 关于任意轴的对称变换 平移(tx, ty)使l 过坐标原点,记为T1 旋转,记R1 对称, 记SYx 旋转-,记 R2 6.5 其它变换 关于任意轴的对称变换 平移(tx, ty)使l 过坐标原点,记为T1 旋转,记R1 对称, 记SYx 旋转-,记 R2 平移(-tx, -ty), 记T2 总变换:T2•R2 • SYx•R1 •T1

6.5 其它变换 错切变换(shear) 依赖轴:坐标保持不变的坐标轴,又称参考轴 方向轴:余下的坐标轴 1、以y 轴为依赖轴的错切变换 6.5 其它变换 错切变换(shear) 依赖轴:坐标保持不变的坐标轴,又称参考轴 方向轴:余下的坐标轴 1、以y 轴为依赖轴的错切变换 (1)以 y = 0为参考轴(坐标保持不变) shx为沿x轴移动的距离

6.5 其它变换 (2)以 y = yref 为参考轴 x׳ = x + shx ( y – yref) y׳ = y

6.5 其它变换 2、以x轴为依赖轴的错切变换

6.5 其它变换 仿射变换 affine transformation 二维线性变换的一般形式 特点:保持平行线间的平行关系 6.5 其它变换 仿射变换 affine transformation 二维线性变换的一般形式 平移,旋转,放缩,对称和错切是特例 特点:保持平行线间的平行关系

6.5 其它变换 例:证明二维复合变换的矩阵总能表示为: 证明:

6.6 三维几何变换 三维齐次坐标 右手坐标系 (x, y, z)点对应的齐次坐标为 标准齐次坐标(x, y, z, 1) 旋转方向 6.6 三维几何变换 三维齐次坐标 (x, y, z)点对应的齐次坐标为 标准齐次坐标(x, y, z, 1) 右手坐标系 旋转方向 当拇指与坐标轴同向时, 四指所指方向为绕该轴的 正旋转方向

6.6 三维几何变换 平移变换 位移量:(tx, ty , tz) 放缩变换 参照点为坐标原点

6.6 三维几何变换 旋转变换 绕x轴 绕y轴 y x z

6.6 三维几何变换 绕z轴 错切变换 以z为依赖轴 y x z

6.6 三维几何变换 对称变换 关于坐标平面 xy 的对称变换 其它坐标平面类似

6.6 三维几何变换 三维几何变换的一般形式 (1)前三行和前三列对应旋转和放缩变换 (2)第四列的前三个元素对应平移变换 6.6 三维几何变换 三维几何变换的一般形式 (1)前三行和前三列对应旋转和放缩变换 (2)第四列的前三个元素对应平移变换 (3)第四行前三个元素对应投影变换

6.6 三维几何变换 思考题:绕任意轴旋转 思路:将矢量 P1P2 变换后与坐标轴重合,再用基本旋转变换实现旋转,再逆变换到原位置 步骤: 6.6 三维几何变换 思考题:绕任意轴旋转 思路:将矢量 P1P2 变换后与坐标轴重合,再用基本旋转变换实现旋转,再逆变换到原位置 步骤: 先平移,将 P1 平移到坐标原点 绕 y 和 z 轴旋转使矢量 P1P2 与 x 轴重和 。。。 α β

6.7 图形对象的几何变换 图形对象 方法 前提 点,线段,多边形,圆,字符 先生成点集,再对其中的点进行变换 对参数变换 6.7 图形对象的几何变换 图形对象 点,线段,多边形,圆,字符 方法 先生成点集,再对其中的点进行变换 运算量大 对参数变换 线段:两个端点 多边形:各顶点 圆:圆心和半径 前提 图形对象的几何表示是否发生变化?

6.8 OpenGL几何变换函数 说明 基本几何变换函数 在核心库中,每种几何变换是一个独立的函数 所有变换都是在三维坐标系中定义 平移函数:glTranslate{fd}(tx, ty, tz) 对二维变换而言,取tz=0 旋转函数:glRotate{fd}(theta, vx, vy, vz) 向量(vx, vy, vz)为通过坐标原点旋转轴 theta为旋转角的度数 放缩函数:glScale{fd}(sx, sy, sz) 相对坐标原点的缩放 当参数为负时,相对于平面反射变换

6.8 OpenGL几何变换函数 例程序 6-1 注意: 几何变换矩阵只有1个 void display (void) { glColor3f (0.0, 0.0, 1.0); glRecti (20, 50, 100, 80); glColor3f (1.0, 0.0, 0.0); glTranslatef (-120.0, -40.0, 0.0); glRecti (20, 50, 100, 80); glLoadIdentity ( ); glColor3f (1.0, 0.0, 1.0); glRotatef (135.0, 0.0, 0.0, 1.0);glRecti (20, 50, 100, 80); glLoadIdentity ( ); glColor3f ( 0.0, 1.0,0.0); glScalef (0.5, -1.0, 1.0); glRecti (20, 50, 100, 80); glColor3f(0,0,0); glLoadIdentity ( ); glBegin(GL_LINES); glVertex2i(0,-Y/2+5); glVertex2i(0,Y/2-5); glVertex2i(X/2-5,0); glVertex2i(-X/2+5,0); glEnd(); glutSwapBuffers(); } 例程序 6-1 注意: 几何变换矩阵只有1个

6.8 OpenGL几何变换函数 例6-1(续) #include <gl/glut.h> #include <stdlib.h> #include <math.h> int X=0,Y=0; void Reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-width/2, width/2, -height/2, height/2); glMatrixMode(GL_MODELVIEW);//定义模型观察变换矩阵 glClear (GL_COLOR_BUFFER_BIT); X=width, Y=height; } 例6-1(续) void init (void) { glClearColor (1.0, 1.0, 1.0, 0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0, 250.0, 0.0, 250.0); }

6.8 OpenGL几何变换函数 例6-1(续) int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (250, 250); glutInitWindowPosition (300, 300); glutCreateWindow ("Transformation"); init (); glutDisplayFunc(display); glutReshapeFunc(Reshape); glutMainLoop(); return 0; }

6.8 OpenGL几何变换函数 矩阵操作 矩阵栈 模型观察矩阵:glMatrixMode(GL_MODELVIEW) 建立当前观察矩阵 还有两种方式:纹理和颜色模式,默认为观察模式 设置当前矩阵为单位矩阵:glLoadIdentity() 矩阵栈 4种:观察、投影、纹理和颜色 初始状态下,每栈仅包含一单位栈 压栈:glPushMatrix() 出栈:glPopMatrix()

6.8 OpenGL几何变换函数 例6-2 机器人 手臂 #include <GL/glut.h> #define BASE_HEIGHT 2.0 #define BASE_RADIUS 1.0 #define LOWER_ARM_HEIGHT 5.0 #define LOWER_ARM_WIDTH 0.5 #define UPPER_ARM_HEIGHT 5.0 #define UPPER_ARM_WIDTH 0.5 typedef float point[3]; GLfloat theta[] = {0.0,0.0,0.0}; GLint axis = 0; GLUquadricObj *p; /* pointer to quadric(二次曲面) object */ void myinit() { glClearColor(1.0, 1.0, 1.0, 1.0); glColor3f(1.0, 0.0, 0.0); p=gluNewQuadric(); /* allocate quadric object */ gluQuadricDrawStyle(p, GLU_LINE); /* render it as wireframe */ } 例6-2 机器人 手臂

6.8 OpenGL几何变换函数 例6-2(续) void base() { glPushMatrix();/* rotate cylinder to align with y axis */ glRotatef(-90.0, 1.0, 0.0, 0.0);/* cyliner aligned with z axis*/ gluCylinder(p, BASE_RADIUS, BASE_RADIUS, BASE_HEIGHT, 5, 5); glPopMatrix(); } void upper_arm() { glPushMatrix(); glTranslatef(0.0, 0.5*UPPER_ARM_HEIGHT, 0.0); glScalef(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH); glutWireCube(1.0); glPopMatrix(); void lower_arm() { glPushMatrix(); glTranslatef(0.0, 0.5*LOWER_ARM_HEIGHT, 0.0); glScalef( LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH); glutWireCube(1.0);

6.8 OpenGL几何变换函数 void display(void) {/* Accumulate ModelView Matrix as we traverse tree */ glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glColor3f(1.0, 0.0, 0.0); glRotatef(theta[0], 0.0, 1.0, 0.0); base(); glTranslatef(0.0, BASE_HEIGHT, 0.0); glRotatef(theta[1], 0.0, 0.0, 1.0); lower_arm(); glTranslatef(0.0, LOWER_ARM_HEIGHT, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); upper_arm(); glutSwapBuffers(); } void mouse(int btn, int state, int x, int y) {/* left button increase joint angle, right button decreases it */ if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) {theta[axis] += 5.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0;} if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {theta[axis] -= 5.0; if( theta[axis] < 360.0 ) theta[axis] += 360.0;} display();}

6.8 OpenGL几何变换函数 void menu(int id) {/* menu selects which angle to change or whether to quit */ if(id == 1 ) axis=0; if(id == 2) axis=1; if(id == 3 ) axis=2; if(id ==4 ) exit(0); } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-10.0, 10.0, -5.0 * (GLfloat) h / (GLfloat) w, 15.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-10.0 * (GLfloat) w / (GLfloat) h, 10.0 * (GLfloat) w / (GLfloat) h, -5.0, 15.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW);

6.8 OpenGL几何变换函数 void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("robot"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutCreateMenu(menu); glutAddMenuEntry("base", 1); glutAddMenuEntry("lower arm", 2); glutAddMenuEntry("upper arm", 3); glutAddMenuEntry("quit", 4); glutAttachMenu(GLUT_MIDDLE_BUTTON); glutMainLoop(); }

6.8 OpenGL几何变换函数 使用双缓冲 空闲函数(回调函数) 重绘制函数 以GLUT_DOUBLE为参数调用glutInitDisplayMode,设置双缓存的窗口模式 在显示回调函数的最后调用glutSwapBuffers()函数 空闲函数(回调函数) 定义:如 void spinCube() 功能:程序不受用户干预时执行spinCube()函数 注册:glutIdleFunc(spinCube) (在main函数中调用) 重绘制函数 glutPostRedisplay()

6.8 OpenGL几何变换函数 例6-3:旋转的立方体 8个顶点的颜色不同 不停地旋转 鼠标控制改变方向 #include <stdlib.h> #include <GL/glut.h> //定义顶点坐标和颜色 GLfloat vertices[][3] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0}, {1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0}, {1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}}; GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0}, {1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0}};

6.8 OpenGL几何变换函数 void polygon(int a, int b, int c , int d) {/* draw a polygon via list of vertices */ glBegin(GL_POLYGON); glColor3fv(colors[a]); glVertex3fv(vertices[a]); glColor3fv(colors[b]); glVertex3fv(vertices[b]); glColor3fv(colors[c]); glVertex3fv(vertices[c]); glColor3fv(colors[d]); glVertex3fv(vertices[d]); glEnd(); } void colorcube(void){/* map vertices to faces */ polygon(0,3,2,1); polygon(2,3,7,6); polygon(0,4,7,3); polygon(1,2,6,5); polygon(4,5,6,7); polygon(0,1,5,4);

6.8 OpenGL几何变换函数 static GLfloat theta[] = {0.0,0.0,0.0}; static GLint axis = 2; void display(void) { /* display callback, clear frame buffer and z buffer, rotate cube and draw, swap buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); colorcube(); glutSwapBuffers(); } void spinCube() {/* Idle callback, spin cube 2 degrees about selected axis */ theta[axis] += 2.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0; /* display(); */ glutPostRedisplay();

6.8 OpenGL几何变换函数 void mouse(int btn, int state, int x, int y) {/* mouse callback, selects an axis about which to rotate */ if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0; if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1; if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2; } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW);

6.8 OpenGL几何变换函数 void main (int argc, char **argv) { /* need both double buffering and z buffer */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE |GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("colorcube"); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutIdleFunc(spinCube); glutMouseFunc(mouse); glEnable(GL_DEPTH_TEST); /* Enable hidden--surface--removal */ glutMainLoop(); }

6.8 OpenGL几何变换函数 矩阵运算 获取当前几何变换矩阵glGetDoublev(GL_MODELVIEW_MATRIX, modelview); modelview为16个元素的实数, 如定义为:GLdouble modelview[16]; 可以用来计算图形变换后的坐标(如多边形顶点坐标) 矩阵相乘:当前矩阵与给定矩阵相乘 void glMultMatrixd( const GLdouble *m );

小结 5种基本变换 复合变换 OpenGL几何变换的应用 平移,旋转,放缩,对称,错切 矩阵表示 限制条件 分解与复合 能根据具体问题计算复杂变换的矩阵 OpenGL几何变换的应用 变换函数 矩阵

作业 1、在坐标系Oxyz中,计算将矢量P(1,1,1)Q(2,2,2)变换到矢量P’(0,0,0) Q’(0,0,1)的变换矩阵 2、假设有一条从 P1 到 P2 的直线上的任意一点 P,证明对任何复合变换,变换后的点 P 都在 P1 和 P2 之间。

上机题一:补充 图形元素的平移、缩放和旋转功能 图形拾取 平移(新位置的定义) 缩放(大小缩放,关于图形的重心) 旋转(绕图形的重心) 旋转90度 选中