上一篇文章中为了简单起见,直接用了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;
}
}
}



源代码下载
窗口重绘还是有问题,郁闷。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2006-07-27 java是传值还是传引用?