计算机图形学 第三章 从图形到图像
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
OpenGL对光栅化的处理
OpenGL规定在子象素级进行光栅化,它将点视为数学点,将直线图元视为数 学直线,将填充图元视为由数学直线包围的区域。程序员应将窗口坐标空间视 为笛卡儿网格,其中的每个网格对应屏幕上的一个象素。 1、光栅化点图元时,如果该点位于象素边界内,则光栅化该点。
2、光栅化直线时,OpenGL光栅化位于两个端点之间的象素。一般而言, OpenGL不会生成线段的第二个顶点。这样对相连线段,可避免绘制一个象素 两次。
第三章 从图形到图像
3.1 图形图像的关系:
1)区别: 图形是用矢量表示的,是用几何学的点、线、面对客观世界建模的 结果。图形中不但包含坐标、拓扑等几何信息,而且可以包含颜色、纹 理等非几何信息。这些信息是设备无关的。 图像是用点阵表示的,其中只有各个点的颜色信息,不含拓扑关系, 也没有几何学的点、线、面。从数学上说,图像是定义域和值域都不连 续的一个函数(数字图像)。 图形和图像各有其优点,图形适合表达几何信息(建模),图像适 合表达视觉信息(照片)。 2)存储: 图形使用矢量文件,图像使用点阵文件。 3)转换关系: 图形通过光栅扫描可以转化为光栅图像;图像通过识别和处理可以 转化为矢量表示的图形形式,但通常它无法完全恢复图形信息。
为了方便活性边表的建立与更新,为每一条扫描线建立一个新边表 (NET[i]),存放在该扫描线第一次出现的边。也就是说,若某边的较低端点 为ymin,则该边就放在扫描线ymin的新边表中。每条扫描线有一个新边表, 新编表可以为空,表示这条扫描线不需要加入新边,而且大多数新编表都应 该为空。
此边的起始x值 Δx
3.3 圆的生成算法(中点画圆法)
圆的特点决定只需要计算1/8圆弧上的点(右上图) (-y,x) 假设圆的方程为:x2+y2=r2 函数F(x,y) = x2+y2-r2,则 F(x,y)>0,对圆外点 F(x,y) = 0,对圆上点 (-y,-x) F(x,y) < 0,对圆内点 在第一象限上半1/8圆弧,如果已得到圆弧的象素点P(xp,yp), (-x,-y) 则下一可能的象素点是P1(xp+1,yp)和P2(xp+1,yp-1)。究竟是 P1还是P2 ,由P1和P2的中点M(xp+1,yp-0.5)的函数值F(xm,ym) 来决定: 如果F(xm,ym)<0,说明圆弧在P1和M之间,取P1点为下一象素。 且下一象素的F(xp+2,yp-0.5)=F(xp+1,yp-0.5)+2xp+3 如果F(xm,ym)≥0,说明圆弧在P2和M之间,则取P2为下一象素。 且下一象素的F(xp+2,yp-1.5)=F(xp+1,yp-0.5)+2(xp-yp)+5 而F(1,r-0.5) = 1.25-r;
实例:用DDA方法在点(0,0)和(5,2)之间画线
n=5 (x0,y0) = (0,0) (xn,yn) = (5,2) k=(2-0)/(5-0) = 0.4
xi 0 1 2
yi 0 0.4 0.8
int(yi+0.5) 0 0 1
3
4 5
1.2
1.6 2
1
2 2
2)Bresenham算法 (最常用)
① 原算法中的浮点计算为: e0=-0.5 ei+1=ei+k=ei+(yn-y0)/(xn-x0) 当ei+1>=0.0时,ei+1=ei+1-1.0; ② 下面开始整型化: 两边同乘(xn-x0),有: (xn-x0) *ei+1= (xn-x0)*ei+(yn-y0) 两边再同乘2,则: 2*(xn-x0) *ei+1= 2*(xn-x0)*ei+2*(yn-y0) 令Ei= 2*(xn-x0) *ei 则有Ei+1=Ei+2*(yn-y0);E0=-(xn-x0); 判别式变为:当Ei+1>=0时,Ei+1=Ei+1-2*(xn-x0) ③ 结论: 通过整型化,算法中只有整型运算,效率大大提高,这正是 Bresenham算法被广泛采用的原因。
3.2 直线生成算法
1)数值微分(DDA:Digital Differential Analyzer )法
过两点(x0,y0),(xn,yn)作直线: 其直线方程为:(y-y0)/(yn-y0)=(x-x0)/(xn-x0) 整理后为:y=kx+b 其中k=(yn-y0)/(xn-x0) 当|k|≤1时,取x方向步长为1, 则有,对中间需要计算的点(i=0,…,n-2) xi+1=xi+1 yi+1=kxi+1+b = k(xi+1)+b = kxi+b+k = yi+k 这里xi为整数,yi、k为浮点数 在屏幕上显示点(x0,y0),(x1,int(y1+0.5)),…,(xn-1,int(yn-1+0.5)),(xn,yn), 则显示出该直线。 由于y方向增量每次小于1,所以直线是连通的。 当|k|≥1时,交换x,y位置进行处理。
为了提高效率,在处理一条扫描线时,仅对与它相交的多边 形的边进行求交运算。与当前扫描线相交的边称为活性边,把它 们按与扫描线交点x坐标递增的顺序存放在一个链表中,此链表称 为活性边表(AET)。活性边表只有一个。
与当前扫面线的x交点坐标 每条扫描线的x增量 本条线段的最大y坐标
扫描线6的活性边表
注:每条扫描线的X增量是斜率的倒数, 可以是任何数值。对水平线需要特 殊处理(扔掉),对垂线其值为0。 不必考虑X的增量大于1的情形,因 为这里生成的是区域,而不是直线, 它总是连通的(对非奇异图形)。
需要考虑的特殊情形
原则:不遗漏点,无重复点。 可以采取的措施: 1)新加入边时,要考虑退出 边的情况,否则会重复计 点。(P1、P7)。 2)适当进行区间合并(过P9 点扫描线)。 3)水平边不参与计算(P6P5、 P3P2)。 4)对三角剖分应当考虑其它 模式(思考)。
P4
P6
P5
P3
P2
P7 P9 P8
1)扫描线算法
扫描线方法通过从多边形最低点到最高点之间的水平扫描,完成对多边 形的扫描转换。对每条扫描线,多边形的扫描转换分为四个步骤: (1)求交:计算扫描线与多边形各边的交点; (2)排序:把所有交点按x值递增顺序排序; (3)配对:奇偶交点配对,每对交点代表扫描线与多边形的一个相交区间。 (4)着色:把相交区间内的象素置成多边形颜色。
此边的最高y值(ymax)
ห้องสมุดไป่ตู้
每条扫描线有新边表(NET[i]),所 有新编表构成NET(可以用数组也可以用 链表)。
算法过程:
void polyfill (polygon, color) 颜色 color;多边形 polygon; { 构造新边表NET(NET[i]为第i条扫描线对应的新边表头,见前页图); y = 最低扫描线号(在这里是1); 初始化活性边表AET为空; 对各条扫描线i,作下列操作 { ▪ 把新边表NET[i]中的边结点插入AET表,并使之按x坐标递增顺序排列; ▪ 将活性边表AET中的边奇偶为区间,对区间内的象素(x, y),用color 着 色; ▪ 检查活性边表AET ,把ymax= i的结点从AET表中删除,其它边的x交点 坐标按增量递增(Δx); } }
实例:用Bresenham方法在点(0,0)和(5,2)之间画线
n=5 (x0,y0) = (0,0) (xn,yn) = (5,2) k=(2-0)/(5-0) = 0.4
xi 0
ei -0.5
yi 0
ei
1
2 3
-0.1
0.3 -0.3
0
1 1
-0.1
-0.7 -0.3
4
5
0.1
2
2
-0.9
Bresenham算法的整型化
P1
P0
2)边界标志算法
边界标志算法的基本思想是: 在帧缓冲器中对多边形的每条边进行直线扫描转换,亦即对多 边形边界所经过的象素打上标志。然后再采用和扫描线算法类似的 方法将位于多边形内的各个区段着上所需颜色。 对每条与多边形相交的扫描线依从左到右的顺序,逐个访问该 扫描线上的象素。使用一个布尔量inside来指示当前点是否在多边形 内的状态。 Inside的初值为假,每当当前访问的象素为被打上边标志的点, 就把inside取反。对未打标志的象素,inside不变。若访问当前象素 时,inside为真,说明该象素在多边形内,则把该象素置为填充颜色。 用软件实现时,扫描线算法与边界标志算法的执行速度几乎相 同,但由于边界标志算法不必建立维护边表以及对它进行排序,所 以边界标志算法更适合硬件实现,这时它的执行速度比有序边表算 法快一至两个数量级。
(-x,y) (x,y)
(y,x)
(y,-x) (x,-y)
程序:
MidCircle18(int r) { int x,y; float f; x=0; y=r; f=1.25-r; //注意f为下一点(1,r-0.5)的判别式 while(x<=y) { point(x,y); if(f<0) f+=2*x+3; else { f+=2*(x-y)+5; y--;} x++; } }
前面已知当直线的斜率|k|≤1时,x方向每次增加 一个步长,y方向增加不到一个步长。 如右图所示,当0≤k≤1时,每次y是否增加取决于 误差项d,d≥0.5,y取直线上面的网格点,否则y取 直线下面的网格点。 即对中间象素(i=0,…, i=n-2),作下列操作: 1)xi+1= xi+1 2)ei+1= ei+k,(e0=-0.5,e不同于d,e=d-0.5) 3)当ei+1≥0时 {yi+1 = yi+1;ei+1= ei+1-1} 否则 yi+1= yi 这里的xi,yi均为整数,即象素点的坐标。e为浮点数。 4)显示(xi+1,yi+1)
作业1:将上述1/8圆伪代码改造为一个完整圆的伪代码,函数名为: MidCircle(int x0, int y0, int r) 其中x0,y0为圆心坐标,r为半径
3.3 多边形的扫描转换
多边形分为三种:凸多边形、凹多边形、含内环的多边形。 多边形的边界不能相交。 凸多边形是指任意两顶点间的连线均在多边形内。 凹多边形是指任意两顶点间的连线有不在多边形内的部分。 含内环的多边形是指多边形内再套有多边形。多边形内的多 边形称为内环。
3、光栅化填充图元时,如果象素中心位于图元的数学边界内时,OpenGL才绘 制该象素。当两个不重叠的填充图元共享同一条边时,这种规则确保相同的象 素不会被绘制两次。
作业2
根据课件第三章中的”扫描线算法“编制一任意多边形的填充程序。 要求:无遗漏点,无重复点。并使用下列数据进行验证: (181,26) (143,133) (19,133) (119,199) (82,306) (181,242) (279,305) (242,199) (342,133) (218,133)