第三章 输出图元 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 中国科学技术大学 视觉计算与可视化实验室

Slides:



Advertisements
Similar presentations
第五节 函数的微分 一、微分的定义 二、微分的几何意义 三、基本初等函数的微分公式与微分运算 法则 四、微分形式不变性 五、微分在近似计算中的应用 六、小结.
Advertisements

2.8 函数的微分 1 微分的定义 2 微分的几何意义 3 微分公式与微分运算法则 4 微分在近似计算中的应用.
2.6 隐函数微分法 第二章 第二章 二、高阶导数 一、隐式定义的函数 三、可微函数的有理幂. 一、隐函数的导数 若由方程 可确定 y 是 x 的函数, 由 表示的函数, 称为显函数. 例如, 可确定显函数 可确定 y 是 x 的函数, 但此隐函数不能显化. 函数为隐函数. 则称此 隐函数求导方法.
计算机图形学 《计算机图形学》 路 通 博士、教授 南京大学计算机科学与技术系课程
§3.4 空间直线的方程.
《解析几何》 -Chapter 3 §7 空间两直线的相关位置.
3.4 空间直线的方程.
《解析几何》 乐山师范学院 0 引言 §1 二次曲线与直线的相关位置.
丰富的图形世界(2).
第三章 数据类型和数据操作 对海量数据进行有效的处理、存储和管理 3.1 数据类型 数据源 数据量 数据结构
第5章 定积分及其应用 基本要求 5.1 定积分的概念与性质 5.2 微积分基本公式 5.3 定积分的换元积分法与分部积分法
第三节 格林公式及其应用(2) 一、曲线积分与路径无关的定义 二、曲线积分与路径无关的条件 三、二元函数的全微分的求积 四、小结.
七 年 级 数 学 第二学期 (苏 科 版) 复习 三角形.
计算机图形学 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 中国科学技术大学 视觉计算与可视化实验室
Hadoop I/O By ShiChaojie.
OpenGL常见问题.
物体识别 3D建图 semantic mapping
辅导课程六.
绘制圆与多边形 椭圆形 绘制椭圆形的方法是 drawOval(x ,y , width , height), 绘制实心椭圆形的方法是
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Introduction to OpenGL (2)
数字图像处理(一).
Detector Drawing in Besvis
数学模型实验课(三) 插值与三维图形.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
双曲线的简单几何性质 杏坛中学 高二数学备课组.
第七章 操作符重载 胡昊 南京大学计算机系软件所.
使用矩阵表示 最小生成树算法.
2.1.2 空间中直线与直线 之间的位置关系.
工业机器人技术基础及应用 主讲人:顾老师
图片与视频数字化. 图片与视频数字化 图片分类 根据图片的构成元素来分 位图: 由像素组成,计算机按顺序存储每个像素点 的颜色信息的保存方式获得的图片。 位图放大后会模糊失真,存储空间相对较大。 矢量图: 由图元组成,通过数学公式计算获得的图片。 放大后不会失真,占用空间小。
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
Chapter 5 Attributes of Output Primitives (图元的属性)
线段的有关计算.
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
Module - pyopengl 應用於2d,3d圖形繪製.
OpenGL几何变换程序.
3.3 垂径定理 第2课时 垂径定理的逆定理.
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
第四章 基本图形生成算法 (二) 2019/4/25 IBM Confidential.
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
第4章 Excel电子表格制作软件 4.4 函数(一).
GLUT 事件處理函式 靜宜大學資管系 蔡奇偉 副教授
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
_13简单的GDI绘图操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
直线和圆的位置关系 ·.
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 平面向量的坐标运算.
第七、八次实验要求.
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
2019/5/21 实验一 离散傅立叶变换的性质及应用 实验报告上传到“作业提交”。 11:21:44.
GIS基本功能 数据存储 与管理 数据采集 数据处理 与编辑 空间查询 空间查询 GIS能做什么? 与分析 叠加分析 缓冲区分析 网络分析
4.6 图形的位似     观察思考:这两幅图片有什么特征? 都是有好几张相似图形组成,每个对应顶点都经过一点.
图片与视频数字化. 图片与视频数字化 图片分类 根据图片的构成元素来分 位图: 由像素组成,计算机按顺序存储每个像素点 的颜色信息的保存方式获得的图片。 位图放大后会模糊失真,存储空间相对较大。 矢量图: 由图元组成,通过数学公式计算获得的图片。 放大后不会失真,占用空间小。
选修1—1 导数的运算与几何意义 高碑店三中 张志华.
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
第二章 图形基元的显示 扫描转换 将图形描述转换成用象素矩阵表示的过程 图形基元(输出图形元素)图形系统能产生的最基本图形 线段、圆、多边形.
1.2轴对称的性质 八 年 级 数 学 备 课 组.
第二章 数字图像处理基础 2.1 图像数字化技术 2.2 数字图像类型 2.3 图像文件格式 2.4 色度学基础与颜色模型.
第三节 数量积 向量积 混合积 一、向量的数量积 二、向量的向量积 三、向量的混合积 四、小结 思考题.
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
PROGRAM 1 Simple E. Angel, Interactive Computer Graphics A Top-Down Approach with OpenGL, Third Edition Addison-Wesley Longman, 2003.
位似.
§4.5 最大公因式的矩阵求法( Ⅱ ).
第二次课后作业答案 函数式编程和逻辑式编程
第三章 图形的平移与旋转.
3.3.2 两点间的距离 山东省临沂第一中学.
Presentation transcript:

第三章 输出图元 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 中国科学技术大学 视觉计算与可视化实验室 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 Telephone:0551-3603484 Email:lfdong@ustc.edu.cn Homepage: http://staff.ustc.edu.cn/~lfdong/research.html 中国科学技术大学 视觉计算与可视化实验室

第三章 输出图元 图元的生成:从图元的参数表示形式(由图形软件包 的使用者指定)到点阵表示形式(光栅显示系统刷新时所 需的表示形式)的转换。

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.1 画线算法 3.1.1 DDA画线算法 3.1.2 Bresenham画线算法 3.1.3 并行画线算法 3.1.4 画线算法的讨论

3.1.1 DDA画线算法 直线段生成 求与直线段充分接近的 像素集 像素间网格均匀 坐标是整型 假设 直线段的宽度为1 线段的生成

3.1.1 DDA画线算法 数字微分(DDA)画线算法 (Digital Differential Analyzer)

3.1.1 DDA画线算法 数字微分(DDA)画线算法 (digital differential analyzer) 直接求交算法: 划分区间[0, 1],dt=1/n 计算坐标 取整 复杂度:乘法+加法+取整

3.1.1 DDA画线算法 DDA增量算法 xi+1=x1+∆x*ti+1=xi+∆x*dt=xi+xinc yi+1=y1+∆y*ti+1=yi+∆y*dt=yi+yinc 复杂度:加法+取整

3.1.1 DDA画线算法 DDA算法优点 DDA算法缺点: xi+1=xi+xinc yi+1=yi+yinc 利用光栅特性消除了直线方程中的乘法,比直接使用直线方程的计算速度快! DDA算法缺点: 取整误差的积累使得对于较长线段所计算的像素位置偏离实际线段。 需要进行浮点数运算。 运行效率低。 不便于用硬件实现 。

3.1 画线算法 3.1.1 DDA画线算法 3.1.2 Bresenham画线算法 3.1.3 并行画线算法 3.1.4 画线算法的讨论

3.1.2 Bresenham画线算法 目标:消除DDA算法中的浮点运算 线段的端点坐标:(x1,y1)和(x2,y2) 线段方程:y=mx+b

3.1.2 Bresenham画线算法 Bresenham画线算法思想 (xk,yk)是直线段上的点 H:(xk+1,yk+1) L:(xk+1,yk) A: (xk+1,y)=(xk+1,m(xk+1)+b) dlower>dupper,取H点 dlower<dupper,取L点 dlower=dupper,选择H或L均可 令p= dlower-dupper, p> 0取上像素 (xk+1, yk+1) , p< 0 采用下像素(xk+1, yk)。

3.1.2 Bresenham画线算法 y=m(xk+1)+b dlower=y-yk=m(xk+1)+b-yk dupper=yk+1-y=yk+1-m(xk+1)-b dlower-dupper=2m(xk+1)-2yk+2b-1 m= 2Δy /Δx pk=Δx(dlower-dupper)=2Δy .xk-2Δx .yk+c pk+1= 2Δy .xk+1- 2Δx .yk+1+c pk+1-pk=2Δy(xk+1-xk)-2Δx(yk+1-yk) pk+1=pk +2Δy(xk+1-xk)-2Δx(yk+1-yk) xk+1-xk=1 pk+1=pk +2Δy-2Δx(yk+1-yk) pk+1> 0取上像素,pk+1< 0 取下像素。 yk+1-yk=0或1,取绝于参数pk的符号。

3.1.2 Bresenham画线算法 在x=x1 +1处,dlower=m, dupper=1-m, p1= 2Δy – Δx 只包括整数的加法、减法和左移(乘2)操作,效率高。 适合用硬件实现。 思考:Bresenham画线算法如何应用到其它卦限?

3.1.2 Bresenham画线算法 2月21日作业1 实现一个折线函数,用Bresenham画线算法来显示连接n个输入点的一组线段。当n=1时绘制单个点。

3.1 画线算法 3.1.1 DDA画线算法 3.1.2 Bresenham画线算法 3.1.3 并行画线算法 3.1.4 画线算法的讨论

3.1.3 并行画线算法 让每一个处理器处理一组像素 适用于系统中的处理器非常多 的场合。 给定一条线段,可以得到它的 包围盒,包围盒中共有∆x*∆y 个像素。让每个处理器处理一 个像素,设像素的坐标为(x,y), 则像素到线段的垂直距离: d=A*x+B*y+C 其中,A=-∆y/linelength B=∆x/linelength C=(x1∆x-y1∆x)/linelength 线段的包围盒

3.1.3 并行画线算法 像素到线段的垂直距离: d=A*x+B*y+C 其中,A=-∆y/linelength 线段的包围盒 像素到线段的垂直距离: d=A*x+B*y+C 其中,A=-∆y/linelength B=∆x/linelength C=(x1∆x-y1∆x)/linelength Linelength=(∆x2+∆y2)1/2 d小于某个设定值,该像素就被 设置成指定的线段颜色。可以看出, 这种并行画线算法特别适合于画具有 一定宽度的线段。

3.1 画线算法 3.1.1 DDA画线算法 3.1.2 Bresenham画线算法 3.1.3 并行画线算法 3.1.4 画线算法的讨论

3.1.4 画线算法的讨论 线段端点的次序要求 :线段P1P2与线段P2P1在图元生成后应该生成相同的像素集合,这样才能保证同一线段的像素表示与线段的端点次序无关。 存在问题:前述算法中,线段P1P2与线段P2P1上的点可能不一致。 解决方法:对于|k|≤1的线段,总是以左端点为 起点,从左向右生成;对于|k|>1的线段,总是以下 端点为起点,从下向上生成。

3.1.4 画线算法的讨论 线段的亮度 现象:A比B亮。 原因:A上的像素点密集。 解决方法:图形保真技术。

3.1 画线算法 3.1.1 DDA画线算法 3.1.2 Bresenham画线算法 3.1.3 并行画线算法 3.1.4 画线算法的讨论

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.2 帧缓冲器的装载 addr(x,y)=addr(0,0)+y*xmax+x addr(x+1,y)=addr(x,y)+1 addr(x+1,y+1)=addr(x,y)+xmax+1

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.3 圆、椭圆的生成 3.3.1 圆的生成 3.3.2 椭圆的生成

3.3.1 圆的生成 处理对象:圆心在原点的圆弧 圆的八对称性 两种直接离散方法: 离散点: x2+y2=R (x,sqrt(R2-x2)) 离散角度:x=Rcosθ y=Rsinθ 缺点:计算量大。

3.3.1 圆的生成 圆弧的正负划分性 F(x,y)=x2+y2-R2 圆弧外的点:F(X,Y)>0 圆弧内的点:F(X,Y)<0

3.3.1 圆的生成 中点画圆算法的优点: 效率高。 只用到整数的加法、 减法和左移。 (乘2)运算。 适合用硬件实现。 中点画圆算法示意图

3.3.1 圆的生成

3.3.1 圆的生成

3.3.1 圆的生成 2月21日作业2 教材P139 3.21

3.3 圆、椭圆的生成 3.3.1 圆的生成 3.3.2 椭圆的生成

3.3.2 椭圆的生成 椭圆 通过椭圆上任 一点到两个焦点 的距离之和等于 常数。 椭圆方程f(x,y)=ry2x2+rx2y2-rx2ry2=0。 椭圆的对称性。

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.4 其他曲线 3.4.1 画锥曲线 Ax2+By2+Cxy+Dx+Ey+F=0 3.4.2 多项式曲线 3.4.1 画锥曲线 3.4.2 多项式曲线 Ax2+By2+Cxy+Dx+Ey+F=0 y=a0+a1x+a2x2+……an-1xn-1+anxn

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.5 并行曲线画法 圆:等份圆弧或x坐标 椭圆或其它曲线:扫描线分段方法

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行曲线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 多边形的填充 3.9 区域填充图元

3.6 像素编址和对象的几何要素 当对象经扫描转换进帧缓存后,输入描述变换为 对应有限屏幕区域的像素坐标,且显示的光栅图像 可能并不严格符合相关的尺寸。 解决方法: 简单地按照物体边界与像素区域的覆盖量来 调整物体的显示尺寸。 将世界坐标系映射到像素间的屏幕位置,使物 体的边界与像素边界对齐,而不是与像素中心对 齐。 屏幕上( x,y)占据对角位置(x,y)和(x+1,y+1)处 的单位正方形。

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.7 保留显示的物体的几何特性 将物体的几何描述转换为象素 表示时,将把数学上的点转换为有 限的屏幕区域.假如要保留由物体 的输入坐标指定的原始几何度量, 那么在将物体的定义转换到屏幕 显示时,就需要考虑象素的有限尺 寸。

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区

3.8 填充区图元 填充区 表面细分

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区 3.10 OpenGL学习

3.9 多边形填充区 多 边 形:由三个或更多称为顶点的坐标位置描述的 平面图形。 分 类:凸多边形或凹多边形。 分 类:凸多边形或凹多边形。 退化多边形:共线或重叠坐标位置的顶点集。

3.9 多边形填充区 多边形的表示方法 顶点表示 点阵表示

3.9 多边形填充区 逐个判断绘图窗口内的像素: 如何判断点与多边形的内外关系? 逐点判断法程序简单, 速度太慢,效率低!

3.9 多边形填充区 #define MAX 100 Typedef struct { int PolygonNum; // 多边形顶点个数 Point vertexces[MAX] //多边形顶点数组 } Polygon // 多边形结构 void FillPolygonPbyP(Polygon *P,int polygonColor) { int x,y; 计算 ymin,ymax,xmin,xmax; for(y = ymin;y <= ymax;y++) for(x = xmin;x <= xmax;x++) if(IsInside(P,x,y)) PutPixel(x,y,polygonColor); else PutPixel(x,y,backgroundColor); }/*end of FillPolygonPbyP() */

3.9 多边形填充区 射线法 由点Pc(xc,yc)出发向任意方向作射线,计算此射线与 多边形所有交点个数,如果交点个数为奇数,则点在多边 形内部,如果交点个数为偶数,则点在多边形外部.

3.9 多边形填充区 多边形网格由若干个相邻的多边形(polygon)组成, 每个多边形由若干条首尾相连的边(edge)组成,每条边 连接两个顶点(vertice),一个顶点至少连接两条边, 一条边至少属于一个多边形并且至多连接两个相邻的多边 形。

3.9 多边形填充区

3.9 多边形填充区 多边形网格表示的方法: 显式表示 指向顶点表的指针 指向边表的指针 方程表示

3.9 多边形填充区 显式表示: P1={(x1,y1,z1), (x2,y2,z2), (x4,y4,z4)} 显式表示的缺点: 浪费空间 没有给出共享顶点与共享边的信息 重复描画 P1={(x1,y1,z1), (x2,y2,z2), (x4,y4,z4)} P2={(x4,y4,z4), (x2,y2,z2), (x3,y3,z3)}

3.9 多边形填充区 指向顶点表的指针 每个顶点只在顶点表V={(x1,y1,z1), (x2,y2,z2),…, (xn,yn,zn)}中存储一次,每个多边形都用指向顶点表 的指针(或索引)列表来表示。 优点:节省空间,便于修改顶点坐标。 缺点:找出共享某一条边的多边形仍然很困难,在画 多边形网格时,共享边仍然会被画两次。

3.9 多边形填充区 V={V1,V2,V3,V4}={(x1,y1,z1),…, (x4,y4,z4)} P1={V1,V2,V4} P2={V4,V2,V3}

3.9 多边形填充区 指向边表的指针 用指向边表的指针来表示多边形网格时,每个顶点仍然 只在顶点表V中存储一次,但每个多边形不再用指向顶点表 的指针来表示,而是用指向边表的指针来表示。 边表中每条边只存储一次,每条边都包括构成该边的两 个顶点(用在顶点表中的索引来表示)。 V={V1,V2,V3,V4}={(x1,y1,z1),…, (x4,y4,z4)} E={E1,E2,E3,E4,E5}={(V1,V2),(V2,V3),(V3,V4), (V4,V2),(V4,V1)} P1={E1,E4,E5} P2={E2,E3,E4}

3.9 多边形填充区 对多边形网格的典型操作: 确定共享某一顶点的所有边。 确定共享某一顶点或某一条边的所有多边形。 确定构成某一条边的两个顶点。 确定构成某一多边形的所有边。 进行合法性检查(如孤立顶点、边或多边形)等等。

3.9 多边形填充区 例1 #Vertex //点数据 #skinhead //特征名称 0.0000 -31.9007 487.6600 //点的坐标 31.0000 -28.3430 470.4640 63.0000 -29.9017 455.9880 …… #facet //面数据 #skinhead //特征名称 0 1 16 //点的索引值 1 15 16 16 15 13

3.9 多边形填充区 例2 点 31 0 0.300023574785431 26.846787517318 15.5 0.300023574796009 15.5 26.846787517318 0.300023574796009 1.8982025386784e-015 31 0.300023574785431 -15.5 26.846787517318 0.300023574796009 -26.846787517318 15.5 0.300023574796009 …… 网格 624 223 258 257 204 223 257 223 204 192 258 223 259 236 261 226 235 221 226

3.9 多边形填充区 V1 V2 V3 V4 V5 E1 E2 E3 E4 E5 E6 S1 S2 多边形表示例子 顶点表 V1:x1,y1,z1 V2:x1,y1,z1 V3:x1,y1,z1 V4:x1,y1,z1 V5:x1,y1,z1 在边表中扩充了 指向面片表的指针 E1:V1,V2,S1 E2:V2,V3,S1 E3:V3,V1,S1,S2 E4:V3,V4,S2 E5:V4,V5,S2 E6:V5,V1,S2 边表 E1:V1,V2 E2:V3,V4 E3:V1,V3 E4:V3,V4 E5:V5,V4 E6:V1,V5 面片表 S1:E1,E2,E3 S2:E3,E4,E5,E6

3.9 多边形填充区 凹多边形识别:凹多边形至少有一个内角大于180。 识别凹多边形:通过计算连续两边向量的叉积来识别凹多边形。 向量叉积:E1╳E2=(E1yE2z-E1zE2y, E1zE2x-E1xE2z, E1xE2y-E1yE2x) V1 V2 V3 V4 V5 V6 E1 E2 E3 E4 E5 E6 (E1 ╳ E2)z>0 (E2 ╳ E3)z>0 (E3 ╳ E4)z<0 (E4 ╳ E5)z>0 (E5 ╳ E6)z>0 (E6 ╳ E1)z>0

3.9 多边形填充区 分割凹多边形:向量方法 E1= (1,0,0) E2= (1,1,0) E3= (1,-1,0) 1 2 E1= (1,0,0) E2= (1,1,0) E3= (1,-1,0) E4= (0,2,0) E5= (-3,0,0) E6= (0,-2,0) E1 ╳ E2=(0,0,1) E2 ╳ E3=(0,0,-2)z<0 E3 ╳ E4=(0,0,2) E4 ╳ E5=(0,0,6) E5 ╳ E6=(0,0,6) E6 ╳ E1=(0,0,2) 延长E2分割多边形。

3.9 多边形填充区 方程表示 Ax+By+Cz+D=0 (A/D)x+(B/D)y+(C/D)z=-1 将平面上不共线的三个点的坐标(x1,y1,z1)、(x2,y2,z2)和(x3,y3,z3)代入上式。 (A/D)x1+(B/D)y1+(C/D)z1=-1 (A/D)x2+(B/D)y2+(C/D)z2=-1 (A/D)x3+(B/D)y3+(C/D)z3=-1

3.9 多边形填充区 假设平面的法向量为N,P为平面上任意一点, 则N.P=-D。 点在平面上 Ax+By+Cz+D=0 点在平面后方 点在平面前方 Ax+By+Cz+D>0

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区 3.10 OpenGL学习

3.10 OpenGL学习 多边形 像素阵列 字符图元 显示列表 显示窗口重定形

3.10 OpenGL学习 glVertex() glRect*() glRecti(200,100,50,250) int vertext1[]={200,100} int vertex2[]={50,250} glRectv(vertex1,vertex2) glBegin(GL_POLYGON) glVertex2iv(p1); glVertex2iv(p2); glVertex2iv(p3); glVertex2iv(p4); glVertex2iv(p5); ……. glEnd();

3.10 OpenGL学习 顶点数组 typedef Glint vertex3[3]; vertex3 pt[8]={ {0,0,0},{0,1,0},{1,0,0},{1,1,0},{0,0,1},{0,1,1}, {1,0,1}, {1,1,1}}; void quad(Glint n1,Glint n2,Glint n3,Glint n4) { glBegin(GL_QUADS); glVertex3iv(pt[n1]); glVertex3iv(pt[n2]); glVertex3iv(pt[n3]); glVertex3iv(pt[n4]); glEnd }

3.10 OpenGL学习 复杂的场景描述需要使用几百或几千个坐标描述.另外还必须为各个对象建立各种属性和观察参数。 对象和场景的描述要使用大量的函数调用,这对对系统资源提出了要求并减慢了图形程序的执行。 为了简化这些问题,OpenGL提供了一种机制来减少函数调用。 glEnableClient(GL_VERTEX_ARRAY); glVertexPointer(3,GL_INT,0,pt); GLubyte vertIndex[]=(6,2,3,7,….); glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE, vertIndex); glDisableClientState(GL_VERTEX_ARRAY);

3.10 OpenGL学习 多边形 像素阵列 字符图元 显示列表 显示窗口重定形

3.10 OpenGL学习 缓存都是离散的内存块,由其空间分辨率n*m和每个像 素的位数(深度)k确定。 把缓冲区k个平面中的任一个称为位平面 (bitplane), 空间中特定位置处的k个元素构成一个像素(pixel), 因此一个像素既可以是一个字节,也可以是一个整数, 甚至是一个浮点数,具体与所用的缓存以及信息的存 放格式有关。

3.10 OpenGL学习 应用程序通过OpenGL函数把信息传送到帧缓存, 或者从帧缓存中获取信息。 当应用程序读写像素时,数据不仅要在内存与 图形卡里的帧缓存之间传输,而且还要重新调整 这些数据的格式,使之与帧缓存匹配。

3.10 OpenGL学习 颜色缓存内容要被输出到显示设备上。 在双缓存中,颜色缓存由两个缓存组成,分别用于读与写,称为前缓存与后缓存。 颜色缓存k确定可以表示的颜色的多少,通常在RGB模式中为24位,在RGBA模式中为32位。 深度缓冲区的k值确定深度的分辨率,通常是32位,这样与浮点数或整数的精度匹配。

3.10 OpenGL学习 数字图像:有限数字数值像素的表示。 合成图像:把几何对象和照相机组合在一起,通过某种 投影过程所得到的结果。 在程序中的图像是像素数组,其大小与类型各异,具 体与图像的类型有关。 对于RGB图像,每一个颜色分量由一个字节表示,则可以定义为:GLubyte myimage[512][512][3]; 如果处理的是单色图像或者灰度图像,那么可以 定义为GLubyte myimage[512][512];

3.10 OpenGL学习 创建图像的一种方法就是利用程序代码。 创建512×512由8×8黑白相间方格构成的图像,代码如下: GLubyte check[512][512][3]; int i,j,k; for(i=0;i<512;i++) for(j=0;j<512;j++) { for(k=0;k<3;k++) check[i][j][k]=0; if((8*(i+j)/64)%64) check[i][j][0]=255; } 从数据获取。 应用光学成像设备摄取。

3.10 OpenGL学习 从数码设备采集的图像是以某种“标准”的格式存储的,最常用格式有BMP、GIF、TIFF、PS、EPS以及JPEG。 以某种顺序存储数据,并进行必要的无损压缩或者有损 压缩编码都是为了满足某类应用软件的需要而提出的。

3.10 OpenGL学习 BMP图像格式:Windows采用的图形文件格式 位图文件头 (bitmap-fileheader) BITMAPFILEHEADER bmfh   位图信息头 (bitmap-information header) BITMAPINFOHEADER bmih  彩色表 (color table) RGBQUAD aColors[]  图象数据阵列字节  BYTE aBitmapBits[] 

3.10 OpenGL学习 位图文件头包含有关于文件类型、文件大小、存放 位置等信息,在Windows 3.0以上版本的位图文件中用  位图文件头包含有关于文件类型、文件大小、存放 位置等信息,在Windows 3.0以上版本的位图文件中用 BITMAPFILEHEADER结构来定义: typedef struct tagBITMAPFILEHEADER {  /*bmfh*/  UINTbfType; DWORDbfSize;  UINTbfReserved1;  UINTbfReserved2;  DWORD bfOffBits; } BITMAPFILEHEADER; 

3.10 OpenGL学习 位图信息头位图信息用BITMAPINFO结构来定义,它由 位图信息头(bitmap-information header)和彩色表(color table)组成,前者用BITMAPINFOHEADER结构定 义,后者用RGBQUAD结构定义。 BITMAPINFO结构具有如下形式:  typedef struct tagBITMAPINFO {  /* bmi */  BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; 

3.10 OpenGL学习 BITMAPINFOHEADER结构包含有位图文件的大小、压缩类型和 颜色格式,其结构定义为:  typedef struct tagBITMAPINFOHEADER { /* bmih */  DWORD biSize;  LONG biWidth;  LONG biHeight;  WORD biPlanes;  WORD biBitCount;  DWORD biCompression;  DWORD biSizeImage;  LONG biXPelsPerMeter;  LONG biYPelsPerMeter;  DWORD biClrUsed;  DWORD biClrImportant; } BITMAPINFOHEADER; 

3.10 OpenGL学习 图像格式与OpenGL 为了从某种格式中解析出像素数组,需要知道格式的 定义。 数组。

3.10 OpenGL学习 在现代的计算机图形系统中,用户程序既可 以向缓存中写入数据,也可以从中读取数据。 对缓存的读写通常是一个矩形的像素块(位块, bit blocks)。

3.10 OpenGL学习 在填充多边形时每次光栅化一条扫描线。 当显示光栅字符时写一小块位。 当进行清除操作时,改变缓存中所有像素的值。 需要在硬件和软件方面提供对位块进行尽可能 有效操作的功能称为位块传送操作,也称为光 栅化操作。

3.10 OpenGL学习 要把源缓存中的一块n×m像素复制到目标缓存中, 那么进行这种操作的位块传送函数应当具有形式。 write_block(source,n,m,x,y,destination,u,v); 本函数调用改变了整个目标块。 针对位块传送操作优化的硬件具有与几何操作的 流水线硬件完全不同的框架。

3.10 OpenGL学习 写入操作的模型和读写内存不同,位块传送操作有 多种写入方式,在写入源像素前可读出目标缓存中 的像素。 像素逻辑运算 源像素: s 目标像素: d 写入的目标像素: d’ d’ = f(s, d) 其中s = 0 或1, d = 0 or 1

3.10 OpenGL学习 源像素与目标像素逐位结合在一起,有16种 可选的函数(表格中的每列为一种)。

3.10 OpenGL学习 定义矩形的形状或图案,可以使用位图和像素图。 像素图:一个彩色像素阵列 像素阵列的参数包括指向颜色矩阵的指针、矩阵的大小及其将要影响的屏幕区域。 实现像素阵列的另一种方法是为矩阵中的每一个元素赋值为0或1。此时,阵列简化成位图,有时也称为掩膜,它指出 一个像素是否被赋予预定颜色。

3.10 OpenGL学习 OpenGL维持了一个当前光栅位置,它是状态的一部分, 可看作在屏幕坐标系中定义的内部光标,指示光栅化像 素写入的位置。 当前光栅位置由glRasterPos*()设置。 例 glRasterPos3f(x,y,z); 三个浮点数定义了一个光栅位置,在变换为屏幕坐标 前要经过模型-视图变换和投影变换。

3.10 OpenGL学习 绘制位图 glBitmap(width, height, x0, y0, xi, yi, bitmap) width和height的单位是位,表示bitmap 的行数和 列数。 x0, y0是相对于当前光栅位置的偏移值,给出了位 图左下角的起始绘制位置。 xi, yi表示位图绘制后当前光栅的移动值。

3.10 OpenGL学习 例子:棋盘 GLubyte wb[2] = {0x00, 0xff}; GLubyte check[512]; int i, j; for(i=0; i<64; i++) for (j=0; j<64, j++) check[i*8+j] = wb[(i/8+j)%2]; glBitmap( 64, 64, 0.0, 0.0, 0.0, 0.0, check);

3.10 OpenGL学习 光栅颜色来自于用glColor*()设置的绘图颜色。 最后一次调用glRasterPos*()时的当前绘图颜色作为 光栅颜色。 glColor3d(1.0,0.0,0.0); glRasterPos3d(x,y,z); glColor3d(0.0,0.0,1.0); glBitmap(…); glBegin(GL_LINES); glVertex3d(…); glEnd(); 几何体以蓝色绘制,位图采用红色显示。

3.10 OpenGL学习 处理器内存->帧缓存 glDrawPixels(width,height,format,type,myimage); 从当前光栅位置开始写入像素格式与类型。 格式format描述图像在处理器内存中的存储格式。 图像格式:RGB, RGBA, 颜色索引 类型type是在应用程序中所采用的数据类型:int, float 例如: GLubytemyimage[512][512][3]; glDrawPixels(512,512,GL_RGB, GL_UNSIGNED_BYTE, myimage);

3.10 OpenGL学习 帧缓存->处理器内存 glReadPixels(x,y,width,height,format,type, myimage) x,y:帧缓存中的开始像素位置 width,height:大小 format:图像格式 type:像素类型 myimage:指向处理器内存的指针 GLubyte myimage[512][512][3]; glReadPixels(0,0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, myimage);

3.10 OpenGL学习 帧缓存->帧缓存 将一块像素数据从OpenGL缓存的一个位置复制到另一个位置。 glCopyPixels(xmin,ymin,width,height,pixelValue) xmin,ymin:块的左下角屏幕坐标位置 width,height:要复制的列数和行数 pixelValue:要复制的数据种类,可以取GL_COLOR、GL_DEPTH和GL_STENCIL。 glCopyPixels (0,0, 100, 100, GL_COLOR);

3.10 OpenGL学习 多边形 像素阵列 字符图元 显示列表 显示窗口重定形

3.10 OpenGL学习 glutBitmapCharacter(font,character) 显示字符串 glRasterPosition2i(x,y) for(k=0;k<36;k++) glutBitmapCharacter(GLUT_BITMAP_9_BY_15, text[k]); 显示轮廓字符 glutStrokeCharacter(font,character)

3.10 OpenGL学习 多边形 像素阵列 字符图元 显示列表 显示窗口重定形

3.10 OpenGL学习 将对象描述成一个命名的语句序列并存储起来,称为 显示列表。 使用glNewList/glEndList函数包围一组OpenGL命令 就可形成显示列表。 glNewList(listID,listMode) . glEndList(); 让OpenGL生成一个标志 listID=glGenLists(1); 查询 glIsList(listID); 删除 glDeleteLists(startID,nLists);

3.10 OpenGL学习 例: regHex=glGenLists(1); glNewList(regHex,GL_COMPILE); glBegin(GL_POLYGON); for(k=0;k<6;k++){ theta=TWO_PI*k/6.0; x=200+150*cos(theta); y=200+150*sin(theta); } glEnd(); glEndList(); glCallList(regHex);

3.10 OpenGL学习 例:字体的存储 光栅字体的显示速度比矢量字体快很多。 假设要定义8x13字体中的128个字符,可以如下应用数组 GLubyte my_font[128][13]; 可以应用显示列表定义字体 base=glGenLists(128); for(i=0;i<128;i++){ glNewList(base+i, GL_COMPILE); glBitMap(8,13,0.0,2.0,10.0,0.0,my_font[i]); glEndList();} 注意:每个字符从当前光栅位置上移2位开始,当字符绘 制后,向右平移2位,这样字符间有2位的水平和竖直间距。

3.10 OpenGL学习 多边形 像素阵列 字符图元 显示列表 显示窗口重定形

3.10 OpenGL学习 窗口重定形函数 glutReshapeFunc(winReshapeFcn)

3.10 OpenGL学习 #include <GL/glut.h> #include <math.h> #include <stdlib.h> const double TWO_PI = 6.2831853; /* Initial display-window size. */ GLsizei winWidth = 400, winHeight = 400; GLuint regHex; class screenPt { public: GLint x, y; };

3.10 OpenGL学习 static void init (void) { screenPt hexVertex, circCtr; GLdouble theta; GLint k; /* Set circle center coordinates. */ circCtr.x = winWidth / 2; circCtr.y = winHeight / 2; glClearColor (1.0, 1.0, 1.0, 0.0);// Display-window color = white. /* Set up a display list for a red regular hexagon. * Vertices for the hexagon are six equally spaced * points around the circumference of a circle. */

3.10 OpenGL学习 例子 regHex = glGenLists (1); // Get an identifier for the display list. glNewList (regHex, GL_COMPILE); glColor3f (1.0, 0.0, 0.0); // Set fill color for hexagon to red. glBegin (GL_POLYGON); for (k = 0; k < 6; k++) { theta = TWO_PI * k / 6.0; hexVertex.x = circCtr.x + 150 * cos (theta); hexVertex.y = circCtr.y + 150 * sin (theta); glVertex2i (hexVertex.x, hexVertex.y); } glEnd ( ); glEndList ( ); } void regHexagon (void) { glClear (GL_COLOR_BUFFER_BIT); glCallList (regHex); glFlush ( ); }

3.10 OpenGL学习 void winReshapeFcn (int newWidth, int newHeight) { glMatrixMode (GL_PROJECTION); glLoadIdentity ( ); gluOrtho2D (0.0, (GLdouble) newWidth, 0.0, (GLdouble) newHeight); glClear (GL_COLOR_BUFFER_BIT); } void main (int argc, char** argv) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition (100, 100); glutInitWindowSize (winWidth, winHeight); glutCreateWindow ("Reshape-Function & Display-List Example"); init ( ); glutDisplayFunc (regHexagon); glutReshapeFunc (winReshapeFcn); glutMainLoop ( ); }

3.10 OpenGL学习

第三章 输出图元 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.1 画线算法 3.2 帧缓冲器的装载 3.3 圆、椭圆和圆弧的生成 3.4 其它曲线 3.5 并行画线算法 3.6 像素编址和对象的几何要素 3.7 保留显示物体的几何特性 3.8 填充区图元 3.9 多边形填充区 3.10 OpenGL学习

计算机图形学 谢谢 欢迎交流! 更多信息请参见 http://staff.ustc.edu.cn/~lfdong/research.html