第2-3讲基本图形生成算法(4学时)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•e初=-0.5, •每走一步有e=e+k。
•if (e>0) then e=e-1
k k k k k d d d d
改进的Brensemham算法绘制直线的原理
算法步骤为:
1.输入直线的两端点P0(x0,y0)和P1(x1,y1)。
2.计算初始值△x、△y、e=-0.5、x=x0、y=y0。
3.绘制点(x,y)。
思考:为什么?
直线的DDA算法程序
void dda(int x1,int y1,int x2,int y2) //直线DDA { int k,i; float x, y, dx, dy; k = abs(x2-x1); if (abs(y2-y1)>k) k = abs(y2-y1); dx = float(x2-x1)/k; dy = float(y2-y1)/k; x=float(x1+0.5); y=float(y1+0.5); for (i=0;i<k;i++){ gl_Point(int(x), int(y)); 图中圆黑点表示用 x = x+dx; DDA法生成的直线 y = y+dy; } }// end DDA
k k k k k d d d d
改进的Brensemham算法绘制直线的原理
算法步骤: 1.输入直线的两端点P0(x0,y0)和P1(x1,y1)。 2.计算初始值△x、△y、d=0、x=x0、y=y0。
3.绘制点(x,y)。
4.d 更 新 为 d+k , 判 断 d 的 符 号 。 若 d>0.5 , 则 (x,y) 更 新 为
第二讲
基本图形扫描转换算法
内容提要
1. 2.
3. 4.
直线的扫描转换算法
圆的扫描转换 多边形的填充 反走样
2.1 直线的扫描转换算法
图形的生成: 在指定的输出设备上,根据坐标描述构造二维
几何图形。
图形的扫描转换: 在光栅显示器等数字设备上确定一个最佳
逼近于图形的象素集的过程(连续图形到象素集的转换)。
图5-1
用一系列的象素点来逼近直线
问题描述:


给定直线两端点P0(x0,y0)和P1(x1,y1),画 出该直线。 要求:直、端点准确、色泽均匀、速度快等。 思路:直线方程计算直 线上的各个点
(x1,y1)
y=kx+b
效率低,如何 消除?
(x0,y0)
图5-1
用一系列的象素点来逼近直线
2.1.1 DDA算法——引入增量思想 (Digital Differential Analyzer)
设直线的起点坐标为(xs,ys),终 点坐标为(xe, ye),令Δx= xe xs,

Δy= y y ,则直线方程:
e- s
(Xi,Round(yi))
(Xi+1,yi+1)
k y / x y kx b yi 1 kxi 1 b k ( xi x) b kxi b xk yi xk x 1, yi 1 yi k
k=△y/△x
改进 2:由于算法只用到误差项的符 号,所以,用2e△x来替换e e'=2*(d-0.5)*dx,则 e初=-2*0.5*dx=-△x, 每走一步有e=e+2△y。 if (e>0) then e=2 △x(e-1)=e-2△x
ei 2ei x ei 1 2(ei k )x 2ei x 2kx ei 2y
while(x<x1){
if(d<0){ x++; y++; d += delta2; }else{ x++; d += delta1;
}
glBegin(GL_POINTS); glVertex2s(x,y); glEnd(); } //End While
delta2=2*(a+b);
x=x0; y=y0; glBegin(GL_POINTS); glVertex2s(x,y); glEnd();
正负法的具体实现
设直线的起点和终点分别为(xs,ys)和(xe,ye),直线方程为: 其中
F ( x, y ) ax by c 0 a c x b b
a y s ye
y
b xe x s
c x s ( y e y s ) y s ( xe x s )
x y 0 0 1 0+0.4
y+0.5 0.5 0.9
Int(y) 0 0
4 0 1 2 3 5
k = Δy / Δx Δx = 1, yi +1 = yi + k
2 0.4+0.4 0.8+0.5= 1 1.3 3 1.2 1.7 1
思考: 用DDA法连接 (0,0) 和(3,5)的直线?
0
1
(Xi,yi)
图中圆黑点表示用 DDA法生成的直线
只有一个加法,效率提高
设(xi,yi)是第i步得的直线上的点,则直线上第个i+1点 是(xi+1,yi+1) 当Δx> Δy>0,即直线斜率小于1,应使x方向每次增加1, y方向最多增加1; 当Δy>Δx>0,直线斜率大于1,y与x应交换,y每次增加1, x方向增加1/k.
2.2.1 正负法
基本原理:设圆的圆心在(0,0),半径 为R,则圆的方程为 F(x,y)=x2+y2–R2=0

A y
最后讨论d的初始值,第一个像素应取 (x0,y0) d 0 F ( x0 1, y0 0.5) a( x0 1) b( y0 0.5) c
若d<0,则取右上方像素 P2,下一个像素取:
F ( x0 , y0 ) a 0.5b
由于(x0,y0)在直线上,故F(x0,y0)=0。因此,设第一个像素取 (x0,y0),则
y F(x,y)=0 F(x,y)>0 x F(x,y)<0 F(x,y)=0
y
F(x,y)>0
F(x,y)<0
x
图5-4 直线将平面分为三个区域
基本原理: 假定0≤k≤1,x是最大位移方向 每次X+1,Y=?
Pu(xi+1,yi+1) Q M(xi+1,yi+1/2) P(xi,yi) 图5-5 Pd(xi+1,yi) Brensemham算法生成直线的原理
Bresenham算法的基本思想
Bresenham也是通过在每列象素中确定与理想直线最近的
象素来进行直线的扫描转换。算法原理是,过各行、各列 象素中心构造一组虚拟网格线,按直线从起点到终点的顺 序计算直线与各垂直网格线的交点,然后确定该列象素中 与此交点最近的象素。该算法的巧妙之处在于可以采用增

4.e更新为e+k,判断e的符号。若e>0,则(x,y)更新
为(x+1,y+1),同时将e更新为e-1;否则(x,y)更新为
(x+1,y)。
5.当直线没有画完时,重复步骤3和4。否则结束。
BresenhamLine(int x0,int y0,int x1,int y1) { int x,y,dx,dy; float k,e; dx=x1-x0; dy=y1-y0; k=(double)dy/(double)dx; e=-0.5;x=x0;y=y0; for (i=0;i<=dx;i++) { // gl_Point(x,y); glBegin(GL_POINTS); glVertex2f(int(x), int(y)); glEnd(); x=x+1; e=e+k; if(e>=0) {y=y+1; e=e-1; } } }//end BresenhamLine
要判断点M在直线上,上方还是下方,可将M代入下面的判 别式判断符号即可
d F (M ) F ( x p 1, y p 0.5) a( x p 1) b( y p 0.5) c
d F (M ) F ( x p 1, y p 0.5) a( x p 1) b( y p 0.5) c
d F ( x0 , y0 ) a 0.5b
x x 1
当d>0时, 当d<0时,Baidu Nhomakorabea
d 0 a 0.5b
d d a
中点算法与DDA 算法效率一样。
d d a b y y 1
P=(x,y)
P2
Q M
为避免浮点运算,做如下处理
d 0 2a b
当d>0时, 当d<0时,
2
3
4
5
6
DDA算法是否最优?
1.改进效率 浮点运算改为整数加法 2.直线方程类型改变
2.1.2
正负法(中点画线法)
直线的方程:
y y1 y0 F ( x, y) y kx b 0 , 其中k x x1 x0
该直线方程将平面分为三个区域:
对于直线上的点,F(x,y)=0; 对于直线上方的点,F(x,y)>0; 对于直线下方的点,F(x,y)<0。
} //End MidpointLine
2.1.3 Bresnham算法

DDA每步只做一个加法 正负法每步只做一个整数加法 效率大幅度提高,但是应用范围有限
假定直线段的0≤k≤1 基本原理:
Dr. Jack Elton Bresenham
令k=△y/△x yi+1=yi+k(xi+1–xi)=yi+k
解决的问题:
绘出圆心在原点,半径为整数R的圆 x2+y2==R2
八分法画圆
y y=-x
(-y,x)
(y,x)
y=x
y
(-x,y)
y=x
(x,y)
R
(-x,-y)
(x,-y)
1/8圆弧
x
(-y,-x)
(y,-x)
八分法画圆程序: void circlePoint(int x, int y) { putpixel ( x, y ); putpixel ( y, x ); putpixel ( -y, x ); putpixel ( -x, y ); putpixel ( -x, -y ); putpixel ( -y, -x ); putpixel ( y, -x ); putpixel ( x, -y ); }
(x+1,y+1),同时将d更新为d-1;否则(x,y)更新为(x+1,y)。
5.当直线没有画完时,重复步骤3和4。否则结束。
提高效率,即由浮点加法提高到整数加法
改进1:令e=d-0.5
xi 1 xi 1 y yi 1 (e 0) i 1 (e 0) yi
k k k k k d d d d
改进的Brensemham算法绘制直线的原理
算法步骤: 1.输入直线的两端点P0(x0,y0)和P1(x1,y1)。 2.计算初始值△x、△y、e=-△x、x=x0、y=y0。 3.绘制点(x,y)。 4.e更新为 e+2△y,判断e的符号。若e>0,则(x,y)更新为
量计算,使得对于每一列,只要检查一个误差项的符号,
就可以确定该列的所求象素。
xi 1 xi 1 y yi 1 (d 0.5) i 1 (d 0.5) yi
误差项的计算
d初=0,
x每走一步:d=d+k 一旦y方向上走了一步,d=d-1
P1
d d 2a
d d 2a 2b
中点算法优于 DDA
正负法程序 void MidpointLine(int x0,int y0,int x1,int y1) {int a, b, delta1, delta2, d,x, y; a=y0-y1; b=x1-x0; d=2*a+b; delta1=2*a;
P2
Q P=(x,y)
y 1 y y
M
(d 0) (d 0)
P1
效率高于DDA?
在d>0,取右下方像素P1 ,下一个像素应取哪个,应计算
d1 F ( x 2, y 0.5) a( x 2) b( y 0.5) c d a
d 2 F ( x p 2, y p 1.5) a( x p 2) b( y p 1.5) c d a b
(x+1,y+1) , 同 时 将 e 更 新 为 e-2△x ; 否 则 (x,y) 更 新 为
(x+1,y)。
5.当直线没有画完时,重复步骤3和4。否则结束。
小结


思考:三种直线光栅化算法的优缺点? 启发: 计算机科学问题的核心就是算法 领会算法中所蕴含的创新思想
2.2 圆弧的扫描转换算法
相关文档
最新文档