Wu反走样算法绘制直线段

时间:2021-10-16 06:07:27

Wu反走样算法###

原理:在我看来,Wu反走样算法是在Bresenham算法基础上改进了一番,它给最靠近理想直线/曲线的两个点以不同的亮度值,以达到模糊锯齿的效果。因为人眼看到的是线附近亮度的平均值。

MFC 中给CXXXView类添加函数
void CMy3_4View::wuLine(CPoint p0, CPoint p1)
{
//自定义二维坐标系
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 p, temp;
int dx=p1.x-p0.x;
int dy=p1.y-p0.y;
double k=(dy*1.00)/(dx*1.00);//计算斜率 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, RGB(0,0,0));
}
} else
{
double e=0.00;//增量 if(k>=0 && k<=1)
{
if(dx<0)//p1在左侧,调换
{
temp=p0;
p0=p1;
p1=temp;
}//p0在左下 for(p=p0; p.x<p1.x; p.x++)//主移动方向->x,不包括p1
{
pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
pDC->SetPixelV(p.x, p.y+1, RGB((1-e)*255, (1-e)*255, (1-e)*255));//不同亮度值
e+=k; if(e>=1.0)
{
p.y++;
e-=1;
}
}
/*p0.x+=10;
p1.x+=10;
pDC->MoveTo(p0);
pDC->LineTo(p1);*/
}
else if(k>1)
{
if(dy<0)//p1在左侧,调换
{
temp=p0;
p0=p1;
p1=temp;
}//p0在下方 for(p=p0; p.y<p1.y; p.y++)//主移动方向->y,不包括p1
{
pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
pDC->SetPixelV(p.x+1, p.y, RGB((1-e)*255, (1-e)*255, (1-e)*255));
e+=1.00/(k*1.00); if(e>=1.0)
{
p.x++;
e-=1;
}
}
} else if(k>=-1 && k<0)
{
e=0.00;
if(dx<0)//p1在左上,调换
{
temp=p0;
p0=p1;
p1=temp;
}//p0在左上 for(p=p0; p.x<p1.x; p.x++)//主移动方向->x,不包括p1
{
pDC->SetPixelV(p.x, p.y, RGB(-1*e*255, -1*e*255, -1*e*255));
pDC->SetPixelV(p.x, p.y-1, RGB((1+e)*255, (1+e)*255, (1+e)*255));//这里e是负数!!!
e+=k; if(e<=-1.0)
{
p.y--;
e+=1.0;
}
}
} else if(k<-1)
{
if(dy>0)//p1在上方,调换
{
temp=p0;
p0=p1;
p1=temp;
}//p0在上
for(p=p0; p.y>p1.y; p.y--)//主移动方向->y,不包括p1
{
pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
pDC->SetPixelV(p.x+1, p.y, RGB((1-e)*255, (1-e)*255, (1-e)*255));
e+=-1.0/(k*1.0); if(e>=1.0)
{
p.x++;
e-=1;
}
}
} }
pDC->DeleteDC();
}
VC++ 6.0编译通过!如有错误,或编译不通过,请留言。