Wu反走样算法绘制直线段

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编译通过!如有错误,或编译不通过,请留言。
全部评论

相关推荐

昨天 18:25
已编辑
南京大学 算法工程师
点赞 评论 收藏
分享
数学转码崽:一直给我推,投了又不理,理了又秒挂
点赞 评论 收藏
分享
02-21 23:22
已编辑
重庆大学 Java
神哥不得了:神哥来啦~还是非常不错的。需要注意的是项目的话建议把编号换一下,把前面那个一和二删掉,然后再把123那种换成点,项目的话应该用这两个项目也问题不大,毕竟你的学历还是挺好的,如果换上两个高质量项目的话,获得面试的比例会大一点,不过这两个项目的话应该吃透,也可以找到面试,八股的话就建议先把高频top50的八股多巩固几遍,别看那些假高频题目就行
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务