1、2019/6/19,1,计算机绘图,李哲林,2008.3,3.1 直线的生成 3.2 直线类图形设计 3.3 圆弧的生成 3.4 圆弧类图形设计 3.5 圆弧连接程序设计,第三章 基本图形设计,3.1 直线的生成,1、概述 2、DDA 算法 3、Bresenham 算法,在光栅显示器的荧光屏上生成一个对象,实质上是往帧缓存寄存器的相应单元中填入数据。画一条从(x1, y1)到(x2, y2)的直线,实质上是一个发现最佳逼近直线的象素序列,并填入色彩数据的过程。这个过程也称为直线光栅化。本节介绍在光栅显示器上直线光栅化的最常用的两种算法:直线DDA算法和直线Bresenham算法。,1、概述,C
2、hapter 3,1、概述,在计算机产生的图形中,用到大量的直线,画好直线是非常有意义的,其一般的准则是: 直线应直:由连续点组成的直线要显示在离散网格的平面上,一定会有不经过网格的点,如左下图。在这种情况下,必须选择靠近直线的网格点来逼近这条直线。若选择的好,线就显得较直;否则就会较弯曲,如下图。,直线的端点应该精确:画出的线段如果不准确,往往会使两条线之间不能很好的镶接,如右图。直线的浓度应一致:线段的浓度与单位线段中所显示的点数成正比。要保持线段的浓度均匀端点应该等距分布。只有宇宙平行和成45的线才能做到。,1、概述,由于屏幕上的坐标为整数坐标,则真正作为输出显示为: y输出=trunc
3、(yn),其中函数trunc()是指舍尾的正数。 因此y输出和yn 之间的量化误差最大为1。 为了改善这方面的误差, 使y0的初值增加0.5, 使量化误差在(-0.5,0.5)范围之间。 同理,若直线斜率大于1, 则上述方程的求解步骤可分为: x0=xa+0.5,xn=xn-1+x/y, y0=ya+0.5,yn=yn-1+1, 其中x,y意义同上。 上述解表示y方向积分步长为1, x方向增量为x/y,其他同上。,Chapter 3,2、DDA 直线生成算法,if |xb-xa|yb-ya| then 计算直线在y方向上的增量:length=|yb-ya| else 计算直线在x方向上的增量:
4、length=|xb-xa| 计算x方向的单位增量:dx=(xb-xa)/length 计算y方向的单位增量:dy=(yb-ya)/length 置初值:x=xa+0.5,y=ya+0.5 for i=1 to length do begin输出点(trunc(x), trunc(y)计算下一个点坐标 x=x+dx,y=y+dy end end of algorithm,Chapter 2,10,2、DDA 直线生成算法,例:用DDA算法绘制直线 P0(0,0)至 P1(5,2),x y y+0.5 int(y+0.5) 0 0.0 0 0 1 0.4 0.4+0.5 0 2 0.8 0.8+
5、0.5 1 3 1.2 1.2+0.5 1 4 1.6 1.6+0.5 2 5 2.0 2.5 2,11,图示,12,DDA 小结,优点:在同一坐标上, 不可能连续停留两次。 缺点:在本算法中,开始需要执行一个除法y/x 或 x/y来确定增量,这样用硬件来实现比较复杂和昂贵,用软件实现相对容易些,但效率较低。,Chapter 3,Chapter 3,3、Bresenham 算法,是计算机图形学领域中使用最广泛的直线扫描转换算法。 原理:过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列象素中与此交点最近的象素。该算法的巧妙之处在于采用增量计
6、算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求象素。,假设列坐标象素已经确定为xi,其行坐标为yi 误差项d的初值d00,x坐标每增加1,d的值相应递增直线的斜率值k,即ddk。 d1,就把它减去1,这样保证d在0、1之间。 令ed0.5,e的初值为0.5,增量为k。 当e0时, 取当前象素(xi,yi)的右上方象素(xi1,yi1); 当e0时, 取(xi,yi)右方象素(xi1,yi)。,14,Bresenham Arithmetic,Bresenham Arithmetic,Chapter 2,14,计算x和y方向的增量:dx=|xb-xa|,dy=|yb-ya| 计
7、算递推公式的初值d1: d=2dy-dx 计算两个单位增量:incr1=2dy , incr2=2(dy-dx) if(xaxb) then 置起点为x=xb,y=yb,置终点为xe=xa, ye=ya else 置起点为x=xa,y=ya,置终点为xe=xb,ye=yb 输出起点(x,y) while(xxe) do beginx=x+1if(d0) then d=d+incr1else y=y+1,d=d+incr2输出点(x,y) end end of algorithm,x y e d 0 0 -0.5 0 1 0 -0.1 0.4 2 1 0.3 0.8 3 1 -0.3 1.2-1
8、 4 2 0.1 1.6-1 5 2 -0.5 2-1-1,例:用Bresenham 算法绘制直线 P0(0,0)至 P1(5,2),15,图示,16,Bresenham 小结,优点: 无乘除法(计算坐标时); 在同一坐标上不可能连续停留两次。,Chapter 3,3.2 直线类图形设计,1、倾斜矩形的设计 2、正多边形的设计 3、具体实例,1. 绘制倾斜矩形 Private Sub Rect_Angle(x, y, W, H, th)Dim x1, y1, x2, y2, x3, y3, x4, y4PI = 3.141592654th = th * PI / 180x1 = xy1 = y
9、x2 = x1 + W * Cos(th)y2 = y1 - W * Sin(th)x3 = x2 - H * Sin(th)y3 = y2 - H * Cos(th)x4 = x3 - W * Cos(th)y4 = y3 + W * Sin(th)PictDraw.Line (x1, y1)-(x2, y2)PictDraw.Line -(x3, y3)PictDraw.Line -(x4, y4)PictDraw.Line -(x1, y1) End Sub,3(x3,y3),2(x2,y2),1(x1,y1),4(x4,y4),th,H,W,37,O,38,2. 绘制正多边形,Priv
10、ate Sub draw_poly(r, n, Xc, Yc, th)Dim dq, Xs, Ys, Xn, Yn, i, adq = 2 * PI / nth = th * PI / 180a = thXs = Xc + r * Cos(th)Ys = Yc - r * Sin(th)For i = a To 2 * PI + dq Step dqXn = Xc + r * Cos(th)Yn = Yc - r * Sin(th)FrmMain.PictDraw.Line (Xs, Ys)-(Xn, Yn)Xs = XnYs = Ynth = th + dqNext i End Sub,X,
11、O,Y,1,2,3,0,5,464,(xc,yc),th,r,39,40,3. 绘制树数,Private Sub CmdDraw_Click() AutoRedraw = TruefrmMain.PictDraw.Scale (0, 0)-(640, 480)a = 3.14 / 15#th = 3.14 / 12#给出树干frmMain.PictDraw.Line (150, 400)-(450, 400)frmMain.PictDraw.Line (285, 400)-(300, 180)frmMain.PictDraw.Line (300, 180)-(315, 400) Randomi
12、ze 初始化随机数生成器(系统计时器)For i = 0 To 99 绘制树叶 Xc = 180 + Rnd * 200 Rnd返回01的值Yc = 100 + Rnd * 180For j = 0 To 12X = Xc + 20 * Cos(j * a + th)Y = Yc - 20 * Sin(j * a + th)frmMain.PictDraw.Line (Xc, Yc)-(X, Y)Next jNext i End Sub,分组作业图表,自动生成2序列各10个随机数,模拟采集信号;用4种图表类型绘制(折线图、柱状图、散点图、雷达图); 横坐标表示序号,纵坐标表示采集的数值,用图例表示序列 绘制内容:坐标轴、图例、网格、坐标值、图表。,分组作业图表,提交内容:设计说明(基本流程图、分工、进度安排、参考文献、心得体会)、源代码。 提交时间:4月25日12:00前。() 375141000QQ.COM ,