首先假设所画直线斜率为 0 -1 之间。
则设起点s(x0,y0) , 终点 d(x1,y1) , 则首先求得
deltaX = x2 - x1, deltaY = y2 - y1 , P0= 2 * deltaX - deltaY , 2 * deltaY , 2 * deltaY - 2 * deltaX ;
则按如下方法绘制每一个点:
若P0 < 0 ,则下一个点为 (x0+1 , y0) , P1 = P0 + 2*deltaY ;
若Pk < 0 , 则下一个点为(xk + 1 , yk ) , Pk+1 = Pk + 2 * deltaY ;
推导过程:
接下来考虑斜率大于1的情况:
这时候交换x、y,设pk( xk , yk) ,则pk+1(xk,yk+1)或pk+1(xk+ 1,yk+ 1) ;
最后就是斜率小于0的情况:
可以做线段关于Y轴的轴对称,则此时斜率为正;
具体做法就是,将起始点和终点横坐标都取反(画得到轴对称线),得到的每个点在画点时将横坐标取反即可。
总结以上,则完整的bresenham画线法为:
最后再贴上代码吧,课上写的,写的很繁琐,在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 ;
}
}
}
}
}