第三章 二维图形基础
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
while(k<=length) {
SetPixel(hdc,x,y,RGB(0,0,0)); x=x+deltx; y=y+delty; k=k+1; Sleep(50); } }
2018/5/11
坚持就是胜利
3 Bresenham直线生成算法
Bresenham直线生成算法是由Bresenham提出的一种精确而有效的 光栅线段生成算法,算法的目标是选择表示直线的最佳光栅位置。 为此,算法根据直线的斜率确定选择变量在X方向上或在Y方向上 每次递增一个单位,另一变量的增量为0或1,它取决于实际直线 与最近网格点位置的距离,这一距离称为误差。算法的构思巧妙, 使得每次只需检查误差项的符号即可确定所选象素。
2018/5/11
坚持就是胜利
3.2.1 圆的参数方程生成算法
圆是图形中经常使用的元素,圆被定义为所有离一中心位置 (xc,yc)距离为给定值R的点集,其函数方程为: (x﹣xc)2﹢(y﹣yc)2﹦R2 利用这个方程,我们可以沿X轴从xc﹣R 到xc﹢R以单位步长计算对 应的y值来得到圆周上每点的位置, 但这并非是生成圆的好方法。
2018/5/11
坚持就是胜利
直线的点斜式方程
y﹦m· x﹢b 其中,m表示直线的斜率,b是y轴截距。给定线段的两个端点 (x1,y1)和(x2,y2),可以计算斜率m和截距b: m﹦(y2﹣y1)/(x2﹣x1) b﹦y1﹣m· x1 对任何沿直线给定的x的增量△x,对应的y增量△y: △y﹦m· △x 同样,对应于y的增量△y,x的增量△x为: △x﹦(1/m)△y
2018/5/11
对于斜率值大于1的 线段,只要交换x和 y之间的规则,即沿 Y方向以单位步长增 加并计算最接近线 段路径的x连续值。 考虑到XY平面各种 八分和四分区域间 的对称性, Bresenham算法对任 意斜率的线段具有 通用性。
坚持就是胜利
Bresenham算法直线绘制例子: 考虑绘制从点(0,0)到(8,4)的线 段。 初值计算:x=0 y=0 Δx=8 Δy=4 ( 循环计算过程部分: e﹦-x for k﹦1 To x putpixel(x,y) e﹦e﹢2y If (e≥0) y﹦y﹢1 e﹦e﹣2x endif x﹦x﹢1
2018/5/11
坚持就是胜利
通常,所选象素点与实际的直线位置之间存在差值。当斜率m 在0-1之间时,x每增加一单位,y 应该增加m,记e为y方向上的误 差。当选取实际直线位置上方的象素点时,误差为e﹦m﹣1;当选 取实际直线位置下方的象素点时,误差为e﹦m。 为了简化判断,可首先令误差项的初值为e0﹦-1/2,这样只要 判断e的符号即可。第一步,当 e1﹦m﹢e0≥0,选取上面的象素 点(1,1);当e1﹦m﹢e0<0,选取下面的象素点(1,0)。e1作为 累计误差项供下一步判断继续使用。设第k步的误差为ek,选取上 面象素点后的积累误差为: ek+1﹦ek﹢(m﹣1) 选取下面的象素点后的积累误差为: ek+1﹦ek﹢m
2018/5/11
坚持就是胜利
DDA直线生成算法的伪语言描述
begin if abs(x2﹣x1)≥abs(y2﹣y1) then lenght﹦abs(x2﹣x1) else lenght﹦abs(y2﹣y1) endif △x﹦(x2﹣x1)/lenght △y﹦(y2﹣y1)/lenght x﹦x1 y﹦y1 k﹦1 while(k≤lenght) putpixel(x,y) x﹦x﹢△x y﹦y﹢△y k﹦k﹢1 endwhile end
2018/5/11
坚持就是胜利
修改后的Bresenham直线生成算法描述
由于x、y是整数,因此算法全部运算都只使用整 数,修改后的Bresenham直线生成算法描述如下: begin x﹦x1 y﹦y1 x﹦x2﹣x1 y﹦y2﹣y1 E﹦-x for k﹦1 To x putpixel(x,y) E﹦E﹢2y If (E≥0) y﹦y﹢1 E﹦E﹣2x endif x﹦x﹢1 next k endfor end
2018/5/11
坚持就是胜利
3.1 直线生成算法
最基本的图形显示方式是直线方式。实际上,无论什么复杂图形, 它们无非是由直线段和曲线段组成。而对于曲线及各种复杂的图 形,可以将其离散成许多小直线段,连接各直线来逼近欲生成的 曲线或其它复杂图形,所以一般图形都可以看成是由直线段组成。 因此,直线段生成的质量好坏与速度快慢将直接影响整个图形生 成的质量和速度。在光栅显示器上显示图形是将线段上所有象素 点亮的过程。如果已知直线段两个端点,可以有很多种不同的数 学方法来决定应改变在两端点之间的那些象素的亮度值才能显示 出两点间的直线。在绘图仪上绘直线段,主要决定X、Y方向上的 位移量,这些算法之间主要区别是判别和生成x、y增量的过程和 方法的不同。
2018/5/11
DDA方法计算象素位置要 比直接使用代数方程快。 它利用光栅特性消除了 代数方程中的乘法,而 在X和Y方向使用合适的 增量来逐步沿线段的路 径计算各象素位置。但 浮点增量的连续迭加中 取整误差的积累会使长 线段所计算的象素位置 偏离实际线段,而且算 法中的取整操作和浮点 运算仍然十分耗时。
2018/5/11
坚持就是胜利
以第一象限的直线为例。假 设斜率m在0-1之间。如右图 所示。若通过(0,0)的直线 的斜率m>l/2,它与x﹦1直 线的交点离y﹦l直线较y﹦0 直线近,光栅点(1,1)比 (1,0)更逼近于该直线,因 此应该取象素点(1,1)。如 果斜率m<l/2,则应取象素 点(1,0)。当斜率m﹦l/2 时,差值相同,可以任选 (1,1)或(1,0)象素点。
2018/5/11
坚持就是胜利
DDA直线生成算法
DDA直线生成算法是一种基于上述直线方程的线段扫描转换算法。 在一个坐标轴上以单位间隔增量,决定另一个坐标轴上最靠近线 段路径的对应整数值。为了使产生的直线光滑,应使X、Y两方向 上每一步的增量都不大于一个单位,因此当|m|≤1时,应该使用x 做自变量,而当|m|>1时应该使用y做自变量。也就是说应该选定 x2﹣x1和y2﹣y1中绝对值较大者作为步进的控制量。假定x2﹣x1 的绝对值大于y2﹣y1的绝对值,取x为一个象素单位长,即x 每次 递增一个象素,然后利用下式计算相应的y值: yk+1﹦yk﹢△y﹦yk﹢m· △x 对于|m|>1的线段,可通过计算由Y方向的增量△y引起的改变来 生成直线: xk+1﹦xk﹢△x﹦xk﹢m· △y
2018/5/11
坚持就是胜利
圆的方程绘制方法C++实现
void 圆的方程绘制(HDC hdc) { double xc=300,yc=200,R=150; double x,y; y=yc; for(x=xc-R;x<=450;x++) { y=sqrt(R*R-(x-xc)*(x-xc))+yc; SetPixel(hdc,x,y,RGB(0,0,0)); y=-sqrt(R*R-(x-xc)*(x-xc))+yc; SetPixel(hdc,x,y,RGB(0,0,0)); Sleep(50); } }
2018/5/11
坚持就是胜利
1. 点的生成
点是图形中最基本的图素,直线、曲线以及其它的图元都是点的 集合。在几何学中,一个点既没有大小,也没有维数,点只是表 示坐标系统中一个位置。在计算机图形学中,点是用数值坐标来 表示的。在直角坐标系中点由(x,y) 两个数值组成的坐标表示, 在三维坐标系中点是由(x,y,z)三个数值组成的坐标表示。 在输出设备上输出一个点,就要把应用程序中的坐标信息转换 成所用输出设备的相应位置。对于一个CRT监视器来说,输出一个 点就是要在指定的屏幕位置上打开电子束,使该位置上的荧光点 亮。 在PC机中,点亮屏幕上一个点是由BIOS控制完成的,各种程 序语言中都有描点语句。例如C语言为putpixel(x,y,color)。
坚持就是胜利
DDA直线绘制的C++实现
void DDA直线绘制(HDC hdc) { int k; double x1=50,y1=50,x2=300,y2=350; double x,y,deltx,delty,length; if (fabs(x2-x1)>=fabs(y2-y1)) length=fabs(x2-x1); else length=fabs(y2-y1); deltx=(x2-x1)/length; delty=(y2-y1)/length; x=x1; y=y1; k=1;
2018/5/11
坚持就是胜利
3.2 二次曲线绘制算法
二次曲线是指那些能用二次函数 Ax2﹢Bxy﹢Cy2﹢Dx﹢Ey﹢F﹦0 来表示的曲线,包括圆、椭圆、抛物线、双曲线等。由于图形输出 设备的基本动作是显示象素点或者是画以步长为单位的直线段, 所以,从图形显示器和绘图机上输出的图形,一般除了水平线和 垂直线以外,其他的各种线段,包括直线和曲线,都是由很多的 点和短直线构成的锯齿形线条组成的。也就是说,需要把曲线离 散化,把它们分割成很多短直线段,用这些短直线段组成的折线 来逼近曲线。
2018/5/11
此Bresenham算法在计 算直线斜率和误差项时 要用到浮点算术运算和 除法,如果采用整数算 术运算和避免除法,可 以加快算法的速度。实 际上,误差项e的数值 大小与算法的执行没有 什么关系,相关的只是 e的符号,因此作简单 变换,即可得到整数算 法。
坚持就是胜利
将e乘以2x记为E﹦2xe,则E同e有相同的符号,取代e 判断E的符号确定象素点的过程仍然正确。此时上述算法中各 误差项的表示式做如下变动: 初始误差项: E0﹦2xe0 ﹦ - x ; 积累误差 ek+1﹦ek﹢m修改为: Ek+1﹦2xek+1 ﹦2x(ek﹢y/x) ﹦2xek﹢2y ﹦Ek﹢2y; 如果选取上面的象素点,积累误差还要减去1,修改为: Ek+1﹦2x(ek+1﹣1) ﹦E k+1﹣2x
第三章 二维图形基础
物体的形状和颜色可用象素矩阵或直线线段和多边形 填充区域等基本几何结构来描述。点和直线段是最简 单的几何成分,其它可供构造图形的输出图元有圆及 其它圆锥曲线、二次曲面、样条曲线和曲面、多边形 填充区域以及字符串等。而二维图形的生成是三维图 形生成的基础,研究计算机生成图形需先从二维图形 的生成开始。下面将讨论一些基本二维图元生成技术 和算法,以光栅图形系统的扫描转换方法为基础。
2018/5/11
坚持就是胜利
2. DDA直线生成算法
直线是点的集合,在几何学中直线被定义为两个点之间的最短距 离。也就是说一条直线是指所有在它上面的点的集合。直线是一 维的,即它们具有长度但没有面积。直线可以向一个方向及其相 反的方向无限伸长,这不是计算机图形学中所需要的,在图形学 中研究的对象是直线段。已知线段的起点坐标(x1,y1),终点坐 标(x2,y2),这两点就确定了一条线段。 一般来讲,任何图形输出设备都能准确地画出水平线X和垂直 线Y,或对角线,但要画出一条准确斜线不是件容易的事。在光栅 系统中,线段通过象素绘制,水平和垂直方向的台阶大小受象素 的间隔限制。这就是说,必须在离散位置上对线段取样,并且在 每个取样位置上决定距线段最近的象素,画一条直线实际上就计 算出来一系列与该线靠近的象素。
2018/5/11
坚持就是胜利
Bresenham直线生成算法的伪语言描述
begin x﹦x1 y﹦y1 x﹦x2-x1 y﹦y2-y1 m﹦y/x e﹦-1/2 for k﹦1 to x putpixel(x,y) e﹦e﹢m if(e≥0) y﹦y﹢1 e﹦e﹣1 endif x﹦x﹢1 next k endfor end
2018/5/11
坚持就是胜利
Bresenham直线绘制的C+线绘制(HDC hdc) for(k=1;k<=deltx;++k) { { int k; double x1=50,y1=50,x2=300,y2=300; SetPixel(hdc,x,y,RGB(0,0,0)); E=E+2*delty; double x,y,deltx,delty,E; if(E>=0) { x=x1; y=y+1; y=y1; E=E-2*deltx; deltx=x2-x1; }; delty=y2-y1; x=x+1; E=-deltx; Sleep(50); } }