MFC Bresesnham算法

Bresesnham算法绘制直线段###

Bresenham算法的意义:高效的将图形光栅化。其计算过程中均采用加法运算,故大大减少了程序的开销。

  • 绘制直线段(MFC中)
//传入参数:起点、终点,颜色
void CMy3_4View::Bresenham(CPoint p0, CPoint p1, COLORREF CLR)
{
        //自定义二维坐标系
	CDC *pDC = GetDC();
	CRect rect;
	GetClientRect(&rect);
	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowExt(rect.Width(), rect.Height());
	pDC->SetViewportExt(rect.Width(), -rect.Height());
	pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
	rect.OffsetRect(-rect.Width()/2, -rect.Height()/2);

        //开始绘制
	CPoint temp, p;
	int dx=p1.x-p0.x;
	int dy=p1.y-p0.y;
	double k=dy*1.00/dx*1.00;//斜率
	COLORREF clr=CLR;//直线颜色

        //不同斜率分别讨论
	if(dx==0)//垂线
	{
		if(dy<0)//七点在上方,调换
		{
			temp=p0;
			p0=p1;
			p1=temp;
		}
		for(p=p0; p.y<p1.y; p.y++)//主移动方向->y,不包括p1
		{
			pDC->SetPixelV(p.x, p.y, clr);
		}
	}

	else//非垂线,斜率k,中点误差项d
	{
		double d;
		if(k>1.0)								// k > 1.0
		{
			if(dy<0)
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在左下
			d=1-0.5*k;
			for(p=p0; p.y<p1.y; p.y++)//主移动方向->y,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, clr);
				if(d>=0)
				{
					d+=1-k;
					p.x+=1;
				}
				else
				{
					d+=1;
				}
			}
		}

		else if(k>=0 && k<=1)					// 0 = < k < = 1
		{
			if(dx<0)
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在左下
			d=0.5-k;
			for(p=p0; p.x<p1.x; p.x++)//主移动方向->x,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, clr);
				if(d>=0)
				{
					d=d-k;
				}
				else
				{
					d+=1-k;
					p.y+=1;
				}
			}
		}

		else if(k>=-1 && k<0)					//-1 = < k < 0
		{
			if(dx<0)
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在左上
			d=-0.5-k;
			for(p=p0; p.x<p1.x; p.x++)//主移动方向->x,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, clr);
				if(d>0)
				{
					d-=1+k;
					p.y--;
				}
				else
				{
					d-=k;
				}
			}
		}

		else if(k<-1)								// k < -1.0
		{
			if(dy>0)
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在左上
			d=-1-0.5*k;
			for(p=p0; p.y>p1.y; p.y--)//主移动方向->y,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, clr);
				if(d<0)
				{
					p.x+=1;
					d-=1+k;
				}
				else
				{
					d-=1;
				}
			}
		}

		else
		{pDC->TextOut(0, 0, "ERROR in draw!");}

	}
	pDC->DeleteDC();
}
VC++ 6.0编译通过!
posted @ 2018-09-28 08:55  yocichen  阅读(889)  评论(0编辑  收藏  举报