PAGE 32
PAGE 7
计算机图形学
实验报告
班级 计算机工硕班
学号 220456
姓名 王泽晶
实验一:直线段扫描转换
实验目的
通过本次试验,学生可以掌握直线段的扫描转换算法及其程序设计方法。
实验内容
绘制20*20的网格线,格子X和Y方向间隔均为20像素,网格起始坐标在(20,20)。我们使用此网格模拟像素矩阵(),格子交叉点是像素中心。
输入直线段两端点,可使用以下两种方法之一:
对话框输入
鼠标在网格内以鼠标左键按下-拖动-抬起方式输入。注意:直线段两端点要自动取整到模拟的像素中心位置
进行直线段扫描转换,通过点击鼠标右键调用方式或者菜单调用的方式执行。计算完成后,将扫描转换结果,在模拟的像素矩阵中,使用圆形显示出来。
方法一:直线的中点算法
算法的主要思想:
讨论斜率k∈[1,+∞)上的直线段的中点算法。
对直线,左下方的端点为(x0,y0),右上方的端点为(x1,y1)。直线段的方程为:
现在假定已求得像素(),则如图得
由于直线的斜率k∈[1,+∞),故m=1/k∈(0,1],则
在直线上,区间内存在两个像素NE和E。根据取整原则,当在中点M右方时,取像素NE,否则取像素E,即
若取,则上式变为
计算的递推公式如下:
=
算法的初始条件为:
相应的程序示例:
public function drawLine(pixelDrawer:Function, x0:int,y0:int,x1:int,y1:int):void
{
var dx:Number = x1 - x0;
var dy:Number = y1 - y0;
var x:Number;
var y:Number;
if ((dx == 0) && (dy == 0) )
{
// 两点重合时,直接绘制重合的点
pixelDrawer( x0, y0 );
return;
}
else if ( dx==0 )
{
// 第二点落在X轴上,直接绘制直线上的点
var step:Number = dy / Math.abs(dy);
for (y=y0; y!=y1; y+=step )
pixelDrawer( x0, y );
}
else if ( dy==0 )
{
// 第二点落在Y轴上,直接绘制直线上的点
step = dx / Math.abs(dx);
for (x=x0; x!=x1; x+=step )
pixelDrawer( x, y0 );
}
var stepX:Number = dx / Math.abs(dx);
var stepY:Number = dy / Math.abs(dy);
x = x0, y = y0;
pixelDrawer( x, y ); // 绘制起点
var k:Number = dy / dx;
if ( Math.abs(k)<1.0 ) // 斜率<1的情形,以X为自变量递增
{
var a:Number = -Math.abs(dy);
var b:Number = Math.abs(dx);
var d:Number = 2 * a + b;
var d1:Number = 2 * a;
var d2:Number = 2 * (a + b);
while ( x!=x1 )
{
if ( d<0 ) { x += stepX; y += stepY; d += d2; }
else { x += stepX; d += d1; }
pixelDrawer( x, y );
}
}
else // 斜率>=1的情形,以Y为自变量递增
{
a = -Math.abs(dx);
b = Math.abs(dy);
d = 2 * a + b, d1 = 2 * a, d2 = 2 * (a + b);
while ( y!=y1 )
{
if ( d<0 ) { x += stepX; y += stepY; d += d2; }
else { y += stepY; d += d1; }
pixelDrawer( x, y );
}
}
pixelDrawer( x1, y1 ); // 绘制终点
}
编译