计算机图形图像技术--实验报告参考形式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二直线的生成算法的实现
一、实验目的和要求:
1、理解直线生成的基本原理
2、熟悉直线的生成算法,掌握直线的绘制
3、利用TurboC实现直线生成的DDA 中点画法
二、实验内容:
1、了解直线生成的原理…. 直线DDA算法
对于端点(x0,y0)和(x1,y1)的直线段,直线扫描转换的最简单方法是先算出直线的斜率,然后,从直线的起点开始,确定逼近与直线的y轴坐标。
假设端点坐标均为整数,表示端
点恰在栅格上,让x从起点变化到终
点,每步递增△x,利用直线方程y=
kx+ b可以计算出对应的y轴坐标
y i+1= kx i+1+ b
= k(x i+△x)+ b
= kx i+ b+ k△x (3.1)
= y i+ k△x
取△x=1时,有y i+1= y i+ k,即当x
每递增1时,y递增的值是直线斜率
k。
直线DDA算法就是取直线起点(x0,y0)
作为初始坐标,每一步x递增1,通
过式
(3.1)计算出y轴坐标。
直线DDA 算法也称数值微分算法。
.中点画线算法
和直线DDA算法的讨论相同,在对中点画线算法的讨论中,假定直线斜率|k|≤1。
这种情况下,x每增加1,y最多增加1.假设x轴坐标为x i的与直线最近的像素已经决定为P(x i,y i),则下一个与直线最接近的像素只能是正右方的P1(x i+1,y i)或右上方的P2(x i+1,y i+1)。
以M(x i+1,y i+0.5)表示P1与P2的中点,用Q表示该直线与x= x i+1直
线的交点。
很明显,当M在Q的下方,表明P2离直线更近,应该取P2为下一直线上的点;当M在Q的上方,表明P1离直线更近,应该取P1为下一直线上的点,如果M与Q重合,可以任取P1P2中的一点。
这就是中点画线算法的基本思想。
中点画线算法的实现,关键是建立判别式判断M与Q的位置关系,以及如何合理方便地利用增量算法计算判别式。
假设直线的起点和终点分别是(x0,y0)和(x1,y1),如果直线方程采用隐式方程表示为
F(x,y)=ax+by+c=0 (3.2)
通过简单计算,可得式(3.2)中的a、b、c分别为
a= y0—y1
b= x1— x0
c= x0 y1— x1 y0
由于假定直线斜率|k|≤1,且x0<x1,所以a<0。
依据直线的基本常识,如果一个点(x,y)在直线的上面,有F(x,y)>0;如果一个点(x,y) 在直线的下面,有F(x,y) < 0;如果一个点(x,y)在直线上,有F(x,y)= 0;因此,欲判断前述Q在M的上方还是下方,只要把M代入直线方程是构造的判别式(3.2)并判断它的符号,即
d i= F(M i)= F(x i+1,y i+0.5) = a(x i+1)+b( y i+0.5)+c (3.2)
当d<0时,M在直线的下方,应取右上方的P2作为下一个像素;当d>0时,M在直线的上方,应取正右上方的P1作为下一个像素;当d=0时,可以随便取一个,约定取正右方的P1。
为了简化判别式的计算,注意到d i是x i和y i的线性函数,可以采用增量算法。
当d>0时,取正右方像素P1,令再下一个像素的判别式为
d i+1= F(x i+2,y i+0.5)
= a(x i+2)
+b( y i+0.5)+c
= a(x i+1)+b( y i+0.5)+c+ a
= d i+ a
此时表示判别式的增量为a。
当d<0,取右上方的P2作为下一个像素,令再下一个像素的判别式为
d i+1= F(x i+2,y i+1.5)
= a(x i+2)+b( y i+1.5)+c
= a(x i+1)+b( y i+0.5)+c+ a+ b
= d i+ a+ b 此时表示判别式的增量为a+ b。
直线的最左端是端点(x0,y0),已知F(x0,y0)=0,所以d的初始值计算是 d0= F(x0+1,y0+0.5)
= a(x0+1)+b( y0+0.5)+c
= a+ 0.5b 由于在实际使用中只关心d的符号,且a、b都是整数,因此可在算法实现中以2d的正负代替d的正负,这样可以简化掉d的初始值中的小数,写出仅包含整数运算的算法。
2、编程实现DDA算法、中点画法绘制直线段
三、实验结果分析
// 程序名称:基于 DDA 算法画任意斜率的直线
#include <graphics.h>
#include <conio.h>
// 四舍五入
int Round(float x)
{
return (int)(x < 0 ? x - 0.5 : x + 0.5);
}
// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_DDA(int x1, int y1, int x2, int y2, int color)
{
float x, y; // 当前坐标点
float cx, cy; // x、y 方向上的增量
int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);
x = (float)x1;
y = (float)y1;
cx = (float)(x2 - x1) / steps; cy = (float)(y2 - y1) / steps;
for(int i = 0; i < steps; i++) {
putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画一个 color 颜色的点
x += cx;
y += cy;
}
}
// 主函数
void main()
{
initgraph(640, 480);
// 测试画线
Line_DDA(100, 1, 1, 478, RED);
Line_DDA(1, 478, 638, 1, RED);
// 按任意键退出
getch();
closegraph();
}
// 程序名称:基于中点算法画任意
斜率的直线
#include <graphics.h>
#include <conio.h>
// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_Midpoint(int x1, int y1, int x2, int y2, int color)
{
int x = x1, y = y1;
int a = y1 - y2, b = x2 - x1; int cx = (b >= 0 ? 1 : (b = -b, -1));
int cy = (a <= 0 ? 1 : (a = -a, -1));
putpixel(x, y, color);
int d, d1, d2;
if (-a <= b) // 斜率绝对值<= 1
{
d = 2 * a + b;
d1 = 2 * a;
d2 = 2 * (a + b);
while(x != x2)
{
if (d < 0)
y += cy, d += d2;
else
d += d1;
x += cx;
putpixel(x, y, color); }
}
else // 斜率绝对值 > 1 {
d = 2 * b + a;
d1 = 2 * b;
d2 = 2 * (a + b);
while(y != y2)
{
if(d < 0)
d += d1;
else
x += cx, d += d2;
y += cy;
putpixel(x, y, color);
}
}
}
// 主函数
void main()
{
initgraph(640, 480);
// 测试画线
Line_Midpoint(100, 1, 1, 478,YELLOW);
Line_Midpoint(1, 478, 638, 1, YELLOW);
// 按任意键退出
getch();
closegraph();
}。