计算机图形学实验报告(第33组)
- 格式:doc
- 大小:776.50 KB
- 文档页数:35
院 系: 计算机科学学院 专 业: 年 级:
课程名称: 班 号: 组 号: 指导教师:
2014年 10月 21日 组员 学号 姓名 、 实验名称 直线的扫描转换 实验室
实 验 目 的 或 要 求
一、实验内容 用基本增量算法和Bresenham算法画直线 二、实验目的 1. 理解在显示器上画图与在纸上画图的本质区别; 2. 掌握直线的光栅扫描转换过程; 3. 掌握不同算法绘制直线的思路和优缺点。 三、实验要求 1. 将像素网格表现出来,建立网格坐标系; 2. 用橡皮筋的形式输入参数; 3. 鼠标移动时,显示鼠标当前位置; 4. 显示判别式的计算过程和下一点的选择策略; 5. 记录生成点的坐标,建议用表的形式; 6. 图形生成过程可以重复进行。 实 验 原 理 ( 算 法 基 本 思 想 )
算法原理 过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列象素中与此交点最近的象素。该算法的巧妙之处在于采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求象素。
如图所示,设直线方程为yi+1=yi+k(xi+1-xi)+k。假设列坐标象素已经确定为xi,其行坐标为yi。那么下一个象素的列坐标为xi+1,而行坐标要么为yi,要么递增1为yi+1。是否增1取决于误差项d的值。误差项d的初值d0=0,x坐标每增加1,d的值相应递增直线的斜率值k,即d=d+k。一旦 d≥1,就把它减去1,这样保证d在0、1之间。当d≥0.5时,直线与垂线x=xi+1交点最接近于当前象素(xi,yi)的右上方象素(xi+1,yi+1);而当d<0.5时,更接近于右方象素(xi+1,yi)。为方便计算,令e=d-0.5,e的初值为-0.5,增量为k。当e≥0时,取当前象素(xi,yi)的右上方象素(xi+1,yi+1);而当e<0时,取(xi,yi)右方象素(xi+1,yi)。 程 序 代 码
public void comdHander () { if ((i <= dx) && (dx >= dy && dy >= 0)) { // 0到45度 Graphics g = getGraphics(); g.setColor(Color.RED); g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { Y = Y + 1; de = de - 2 * dx; } X = X + 1; de = de + 2 * dy; i++; }
else if ((i <= dy) && (dy > dx && dx >= 0)) { // 45度到90度 Graphics g = getGraphics(); g.setColor(Color.RED);
g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { X = X + 1; de = de - 2 * dy; } Y = Y + 1; de = de + 2 * dx; i++; }
else if ((i <= dy) && (dx <= 0 && dy > -dx)) { // 90度到135度 Graphics g = getGraphics(); g.setColor(Color.RED); g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { X = X - 1; de = de - 2 * dy; } Y = Y + 1; de = de + 2 * (-dx); i++; }
else if ((i <= -dx) && (dy >= 0 && dy < -dx)) { // 135度到180度 Graphics g = getGraphics(); g.setColor(Color.RED); g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { Y = Y + 1; de = de - 2 * (-dx); } X = X - 1; de = de + 2 * dy; i++; } else if ((i <= -dx) && (-dx >= -dy && -dy >= 0)) { // 180到225度 Graphics g = getGraphics(); g.setColor(Color.RED); g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { Y = Y - 1; de = de - 2 * (-dx); } X = X - 1; de = de + 2 * (-dy); i++; } else if ((i <= -dy) && (-dy > -dx && -dx >= 0)) { // 225度到270度 Graphics g = getGraphics(); g.setColor(Color.RED);
g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { X = X - 1; de = de - 2 * (-dy); } Y = Y - 1; de = de + 2 * (-dx); i++; } else if ((i <= -dy) && (dx >= 0 && -dy > dx)) { // 270度到315度 Graphics g = getGraphics(); g.setColor(Color.RED);
g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { X = X + 1; de = de - 2 * (-dy); } Y = Y - 1; de = de + 2 * dx; i++; } else if ((i <= dx) && (dy < 0 && -dy < dx)) { // 315度到360度 Graphics g = getGraphics(); g.setColor(Color.RED);
g.fillRect(20 * (X + 2), 20 * (Y + 2), 20, 20); if (de >= 0) { Y = Y - 1; de = de - 2 * dx; } X = X + 1; de = de + 2 * (-dy); i++; } }
实 验 结 果 及 分 析
画直线 图为Bresenham算法实现的直线的扫描转换图。从结果可以得到,程序可以显示鼠标的当前坐标,鼠标的起点坐标及鼠标的终点坐标;当执行时,网格会用红方格描出直线的像素点,并在表格中输出相应的D值,X值和Y值,直至描述到直线的最后一个点,程序才结束。 实验名称 圆弧的扫描转换 实验室
实 验 目 的 或 要 求
实验目的: ( 1)掌握圆及圆弧的光栅扫描转换过程; ( 2)掌握不同算法绘制圆弧的技巧和优缺点。
实验要求: (1)将像素网格表现出来,建立网格坐标系; (2)用橡皮筋的形式输入参数; (3)鼠标移动时,显示鼠标当前位置; (4)显示判别式的计算过程和下一点的选择策略; (5)记录生成点的坐标,建议用表的形式; (6)图形生成过程可以重复进行。 实 验 原 理 ( 算 法 基 本 思 想 )
一、中点画圆算法描述 设要显示圆的圆心在原点(0,0),半径为R,起点在(0,R)处,终点在(,)处,顺时针生成八分之一圆,利用对称性扫描转换全部圆。 F(x,y)设要显示圆的圆心在原点(0,0),半径为R,起点在(0,R)处,终点在(,)处,顺时针生成八分之一圆,利用对称性扫描转换全部圆。 为了应用中点画圆法,我们定义一个圆函数F(x,y)=x2+y2-R2 (2-19) 任何点(x,y)的相对位置可由圆函数的符号来检测: 当<0 点(x,y)位于数学圆内 =0 点(x,y)位于数学圆上 >0 点(x,y)位于数学圆外 (2-20) 如下图所示,图中有两条圆弧A和B,假定当前取点为Pi(xi,yi),如果顺时针生成圆,那么下一点只能取正右方的点E(xi+1,yi)或右下方的点SE(xi+1,yi-1)两者之一。
中点画线算法 假设M是E和SE的中点,即 ,则: 1、当F(M)<0时,M在圆内(圆弧A),这说明点E距离圆更近,应取点E作为下一象素点;