欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算机图形学 实验2 直线的扫描转换(MFC中)

程序员文章站 2022-07-14 10:12:57
...

实验目的:

  1. 理解扫描转换的目的
  2. 掌握直线的扫描转换的方法
  3. 理解DDA和Bresenham直线扫描转换算法

一、DDA算法
算法原理: 已知过端点(x0,y0),(x1,y1)的直线段L:y=kx+b,直线斜率为 k=y1-y0/x1-x0 从x的左端点开始,向x右端点步进,步长=1(个象素), yi+1 = yi+k 。
即:当x每递增1,y递增k(即直线斜率) 。
二、Bresenham算法
算法原理:比较从理想直线到位于直线上方的像素的距离t和相邻的位于直线下方的像素的距离s,根据距离误差项的符号确定与理想直线最近的像素。
算法步骤:
当直线斜率0<K<1时:
1.画点(x1,y1), △x=x2-x1, △y=y2-y1,计算初始误差d1= 2△y-△x
2.计算直线的下一点位置: xi+1=xi+1
如果di>=0,则yi+1=yi+1,否则:yi+1=yi
3.画点(xi+1,yi+1)
4.求下一个误差di+1,如果di≧0 则di+1=di+ 2△y-2△x,否则di+1=di+ 2△y
5.i=i+1,如果i<△x+1,转去执行2,否则结束。
实验练习:
请完成下面的程序:
(1) 使用DDA算法实现直线的生成。
代码:

在exView.h中:
public:
	void DDA(CPoint &p1,CPoint &p2,CDC *pdc,COLORREF color);
在exView.cpp中:
void Cex2View::OnDraw(CDC* pDC)
{
	Cex2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	CPoint p1(10,50),p2(100,60);
	DDA(p1,p2,pDC,RGB(0,0,255));
	// TODO: 在此处为本机数据添加绘制代码
}
void Cex2View::DDA(CPoint &p1,CPoint &p2,CDC *pdc,COLORREF color)
{
	double k,dt_x,dt_y;
	dt_x=p2.x-p1.x;
	dt_y=p2.y-p1.y;
	CPoint p=p1;
	pdc->SetPixel(p,color);
	if(!dt_x)
	{
		while(p.y!=p2.y)
		{
			p.y++;
			pdc->SetPixel(p,color);
		}
	}
	else if((k=dt_y/dt_x)<1&&k>-1)
	{
		double temp_y=p.y;
		while(p.x!=p2.x)
		{
			p.x++;
			temp_y+=k;
			p.y=temp_y+0.5;
			pdc->SetPixel(p,color);
		}
	
	}
	else
	{
		double temp_x=p.x;
		while(p.y!=p2.y)
		{
			p.y++;
			temp_x+=k;
			p.x=temp_x+0.5;
			pdc->SetPixel(p,color);
		}
	}

}
截图:

计算机图形学 实验2 直线的扫描转换(MFC中)

(2)使用Bresenham算法斜率 0<k<1的直线的生成

代码:

在BresenhamView.h中:
public:
	void Bresenham(CPoint &p1,CPoint &p2,CDC *pdc,COLORREF color);
在BresenhamView.cpp中:
void CBresenhamView::OnDraw(CDC* pDC)
{
	CBresenhamDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	CPoint p1(10,50),p2(100,60);
	Bresenham(p1,p2,pDC,RGB(255,0,0));
	// TODO: 在此处为本机数据添加绘制代码
}
void CBresenhamView::Bresenham(CPoint &p1,CPoint &p2,CDC *pdc,COLORREF color)
{
	
	double dx,dy,d;
	dx=p2.x-p1.x;
	dy=p2.y-p1.y;
	d=2*dy-dx;
	CPoint p=p1;
	pdc->SetPixel(p,color);
	if((dy/dx)>0&&(dy/dx)<1)
	{
		
		while (p.x!=p2.x)
		{
			double temp_d=d;
			p.x++;
			if(d>=0)
			{
				p.y+=1;
				d=temp_d+2*dy-2*dx;
			}
			else
			{
				p.y=p.y;
				d=temp_d+2*dy;
			}
			pdc->SetPixel(p,color);
		}
	}
}

截图:

计算机图形学 实验2 直线的扫描转换(MFC中)

相关标签: 计算机图形学