bresenham直线画法及推导



首先假设所画直线斜率为 0 -1 之间

则设起点s(x0,y0) , 终点 d(x1,y1) , 则首先求得

deltaX = x2 - x1, deltaY = y2 - y1 , P0= 2 * deltaX - deltaY , 2 * deltaY , 2 * deltaY - 2 * deltaX ;

则按如下方法绘制每一个点:

  1. 绘制s
  2. p0 > 0 ,下一个点为 (x0 + 1 , y0 + 1) , P1 = P0 + 2*deltaY - 2* deltaX ;

P0 < 0 ,则下一个点为 (x0+1 , y0) , P1 = P0 + 2*deltaY ;

  1. 重复步骤2,对于(xk,yk) , Pk > 0 , 则下一个点为(xk + 1 , yk + 1) , P k+1 = Pk + 2 * deltaY - 2 * deltaX ;

Pk < 0 , 则下一个点为(xk + 1 , yk ) , Pk+1 = Pk + 2 * deltaY ;

  1. x = x1 ,算法终止 .

 

推导过程:

bresenham直线画法及推导_第1张图片




接下来考虑斜率大于1的情况:


这时候交换xy,设pk( xk , yk) ,pk+1(xk,yk+1)pk+1(xk+ 1,yk+ 1) ;


  1. P0 = 2*deltaX - deltaY ;
  2. Pk > 0 , 则下一个点为Pk+1(xk+1,yk+1) , Pk+1 = Pk + 2 * deltaX - 2*deltaY ;
  3. Pk<= 0 , 则下一个点为Pk+1(xk,yk+1) , Pk+1 = Pk + 2*deltaX ; 


最后就是斜率小于0的情况:


可以做线段关于Y轴的轴对称,则此时斜率为正;


具体做法就是,将起始点和终点横坐标都取反(画得到轴对称线),得到的每个点在画点时将横坐标取反即可。


 


总结以上,则完整的bresenham画线法为:


bresenham直线画法及推导_第2张图片


最后再贴上代码吧,课上写的,写的很繁琐,在MFC下,用了CDC的SetPixel函数,可以用openGL的

void line(int x1 ,  int y1 , int x2 ,  int y2 )
{
	CPoint s , d ;
	CDC * pDC =  GetWindowDC() ;
	//first make it asc 
	if(y1 == y2 )
	{
		if(x1 <= x2)
		{
			s.x = x1 ;
			d.x = x2 ;
		}
		else
		{
			s.x = x2 ;
			d.x = x1 ;
		}
		for(int i = s.x ; i <= d.x ; i++)
		{
			pDC->SetPixel(i,y1,RGB(0,0,0)) ;
		}
		return ;
	}
	else if( y1 < y2)
	{
		s.x = x1 ;
		s.y = y1 ;
		d.x = x2 ;
		d.y = y2 ;
	}
	else
	{
		d.x = x1 ;
		d.y = y1 ;
		s.x = x2 ;
		s.y = y2 ;
	}
	//judge the k
	float k = ((float)(d.y - s.y))/(d.x - s.x) ;
	if( k > 0)
	{
		if( k < 1.0 )
		{
			int deltaX = d.x - s.x ;
			int deltaY = d.y - s.y ;
			int P = 2*deltaY - deltaX ;
			int delta1 = 2*deltaY ;
			int delta2 = 2*deltaY - 2 *deltaX ;
			CPoint cp ;
			cp.x = s.x ;
			cp.y = s.y ;
			while(cp.x <= d.x)
			{
				pDC->SetPixel(cp,RGB(0,0,0)) ;
				if(P > 0)
				{
					cp.x++ ;
					cp.y++ ;
					P += delta2 ;
				}
				else
				{
					cp.x++ ;
					P += delta1 ;
				}
			}
		}
		else if(k == 1.0 )
		{
			CPoint cp ; 
			cp.x = s.x ;
			cp.y = s.y ;
			while(cp.x <= d.x)
			{
				pDC->SetPixel(cp,RGB(0,0,0)) ;
				cp.x++ ;
				cp.y++ ;
			}
		}
		else
		{
			int deltaX = d.x - s.x ;
			int deltaY = d.y - s.y ;
			int P = 2*deltaX - deltaY ;
			int delta1 = 2 * deltaX ;
			int delta2 = 2 * deltaX - 2*deltaY ;
			CPoint cp ;
			cp.x = s.x ;
			cp.y = s.y ;
			while(cp.y <= d.y)
			{
				pDC->SetPixel(cp,RGB(0,0,0)) ;
				if(P > 0)
				{
					cp.x++ ;
					cp.y++ ;
					P+=delta2 ;
				}
				else
				{
					cp.y++ ;
					P+=delta1 ;
				}
			}
		}
	}
	else
	{
		s.x = - s.x ;
		d.x = - d.x ;
		k = -k ;
		if( k < 1.0 )
		{
			int deltaX = d.x - s.x ;
			int deltaY = d.y - s.y ;
			int P = 2*deltaY - deltaX ;
			int delta1 = 2*deltaY ;
			int delta2 = 2*deltaY - 2 *deltaX ;
			CPoint cp ;
			cp.x = s.x ;
			cp.y = s.y ;
			
			while(cp.x <= d.x)
			{
				pDC->SetPixel(-cp.x,cp.y,RGB(0,0,0)) ;
				if(P > 0)
				{
					cp.x++ ;
					cp.y++ ;
					P += delta2 ;
				}
				else
				{
					cp.x++ ;
					P += delta1 ;
				}
			}
		}
		else if(k == 1.0 )
		{
			CPoint cp ; 
			cp.x = s.x ;
			cp.y = s.y ;
			while(cp.x <= d.x)
			{
				pDC->SetPixel(-cp.x , cp.y,RGB(0,0,0));
				cp.x++ ;
				cp.y++ ;
			}
		}
		else
		{
			int deltaX = d.x - s.x ;
			int deltaY = d.y - s.y ;
			int P = 2*deltaX - deltaY ;
			int delta1 = 2 * deltaX ;
			int delta2 = 2 * deltaX - 2*deltaY ;
			CPoint cp ;
			cp.x = s.x ;
			cp.y = s.y ;
			while(cp.y <= d.y)
			{
				pDC->SetPixel(-cp.x,cp.y,RGB(0,0,0)) ;
				if(P > 0)
				{
					cp.x++ ;
					cp.y++ ;
					P+=delta2 ;
				}
				else
				{
					cp.y++ ;
					P+=delta1 ;
				}
			}
		}
	}
}




你可能感兴趣的:(总结,bresenham,计算机图形学)