上一篇文章中为了简单起见,直接用了CDC的画直线功能,这几天认真研读了图形学的课本,发现书上的算法都是假定直线斜率-1<m<1的情况下适用的,参考了网上的一些资料,将在任意斜率下画直线的两种算法实现如下:
void Line::Draw_DDA(CDC *pDC)
{//用DDA算法画直线
int i;
if(pStart.x==pEnd.x)
{
//为竖线
if(pStart.y<=pEnd.y)
{
for(i=pStart.y;i<=pEnd.y;i++)
pDC->SetPixel(pStart.x,i,m_lPenColor);
}
else
{
for(i=pEnd.y;i<=pStart.y;i++)
pDC->SetPixel(pStart.x,i,m_lPenColor);
}
return;
}
//为横线
if(pStart.y==pEnd.y)
{
if(pStart.x<=pEnd.x)
{
for(i=pStart.x;i<=pEnd.x;i++)
pDC->SetPixel(i,pStart.y,m_lPenColor);
}
else
{
for(i=pEnd.x;i<=pStart.x;i++)
pDC->SetPixel(i,pStart.y,m_lPenColor);
}
return;
}
//为斜线
double m=(pEnd.y-pStart.y)*1.0/(pEnd.x-pStart.x);
float fTemp;
if(abs(m)<=1)
{
if(pStart.x<pEnd.x)
{
fTemp=pStart.y-m;
for(i=pStart.x;i<=pEnd.x;i++)
pDC->SetPixel(i,fTemp+=m,m_lPenColor);
}
else
{
fTemp=pEnd.y-m;
for(i=pEnd.x;i<=pStart.x;i++)
pDC->SetPixel(i,fTemp+=m,m_lPenColor);
}
return;
}
if(pStart.y<pEnd.y)
{
fTemp=pStart.x-1/m;
for(i=pStart.y;i<=pEnd.y;i++)
pDC->SetPixel(fTemp+=1/m,i,m_lPenColor);
}
else
{
fTemp=pEnd.x-1/m;
for(i=pEnd.y;i<=pStart.y;i++)
pDC->SetPixel(fTemp+=1/m,i,m_lPenColor);
}
}
void Line::Draw_Bresenham(CDC *pDC)
{//用Bresenham算法画直线
int i;
if(pStart.x==pEnd.x)
{
//为竖线
if(pStart.y<=pEnd.y)
{
for(i=pStart.y;i<=pEnd.y;i++)
pDC->SetPixel(pStart.x,i,m_lPenColor);
}
else
{
for(i=pEnd.y;i<=pStart.y;i++)
pDC->SetPixel(pStart.x,i,m_lPenColor);
}
return;
}
//为横线
if(pStart.y==pEnd.y)
{
if(pStart.x<=pEnd.x)
{
for(i=pStart.x;i<=pEnd.x;i++)
pDC->SetPixel(i,pStart.y,m_lPenColor);
}
else
{
for(i=pEnd.x;i<=pStart.x;i++)
pDC->SetPixel(i,pStart.y,m_lPenColor);
}
return;
}
//为斜线
float m=(pEnd.y-pStart.y)*1.0/(pEnd.x-pStart.x);
float p;
p=2*m-1;
if(m>0 && m<=1)
{
if(pStart.x<pEnd.x)
{
while(pStart.x<=pEnd.x)
{
pDC->SetPixel(pStart.x++,pStart.y,m_lPenColor);
if(p>=0)
{
p+=2*m-2;
pStart.y++;
}
else
p+=2*m;
}
}
else
{
while(pEnd.x<=pStart.x)
{
pDC->SetPixel(pEnd.x++,pEnd.y,m_lPenColor);
if(p>=0)
{
p+=2*m-2;
pEnd.y++;
}
else
p+=2*m;
}
}
return;
}
p=-2*m-1;
if(m<0 && m>=-1)
{
if(pStart.x<pEnd.x)
{
while(pStart.x<=pEnd.x)
{
pDC->SetPixel(pStart.x++,pStart.y,m_lPenColor);
if(p>=0)
{
p+=-2*m-2;
pStart.y--;
}
else
p+=-2*m;
}
}
else
{
while(pEnd.x<=pStart.x)
{
pDC->SetPixel(pEnd.x++,pEnd.y,m_lPenColor);
if(p>=0)
{
p+=-2*m-2;
pEnd.y--;
}
else
p+=-2*m;
}
}
return;
}
p=2/m-1;
if(m>1)
{
if(pStart.y<pEnd.y)
{
while(pStart.y<=pEnd.y)
{
pDC->SetPixel(pStart.x,pStart.y++,m_lPenColor);
if(p>=0)
{
p+=2/m-2;
pStart.x++;
}
else
p+=2/m;
}
}
else
{
while(pEnd.y<=pStart.y)
{
pDC->SetPixel(pEnd.x,pEnd.y++,m_lPenColor);
if(p>=0)
{
p+=2/m-2;
pEnd.x++;
}
else
p+=2/m;
}
}
return;
}
p=-2/m-1;
if(pStart.y<pEnd.y)
{
while(pStart.y<=pEnd.y)
{
pDC->SetPixel(pStart.x,pStart.y++,m_lPenColor);
if(p>=0)
{
p+=-2/m-2;
pStart.x--;
}
else
p+=-2/m;
}
}
else
{
while(pEnd.y<=pStart.y)
{
pDC->SetPixel(pEnd.x,pEnd.y++,m_lPenColor);
if(p>=0)
{
p+=-2/m-2;
pEnd.x--;
}
else
p+=-2/m;
}
}
}
源代码下载
窗口重绘还是有问题,郁闷。。。
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/07/27/833871.html,如需转载请自行联系原作者