【寒江雪】边界标志算法

边界标志算法对多边形的每条边进行扫描并对该像素打上标志。然后再利用扫描线扫描该多边形,对于与多边形相交的扫描线依从左到右的顺序,逐个访问该扫描线上的像素。使用一个布尔值量inside来表示当前点是否在多边形内。Inside的初值为假,每当当前访问的像素是被打上边标志的点时,就把inside取反。对未标志的像素,inside不变。若访问当前像素时,inside为真,说明该像素在多边形内,则把该像素置为填充色。

伪代码如下:

Void edgeMark_fill(polydef,color){

       对多边形的polydef每条边进行直线扫描转换;

       For(每条与多边形polydef相交的扫描线y)

       {

              If像素x被打上标志

                     Inside=!inside

              Ifinside

                     DrawPixel(x,y,color);

              Else

                     DrawPixel(x,y,backgroundColor);

}

}

 

根据伪代码在C++中实现:

VOID CGraphicDlg::EdgeMarkFill(COLORREF edgeColor, COLORREF fillColor, int yMin, int yMax, int xMin, int xMax)

{

    for (int i = yMin; i <= yMax; i++) {

        bool inside = false;

        //bool flag = false;

        for (int j = xMin; j <= xMax; j++) {

            bool res = CheckEdgeMark(j, i, edgeColor);

            if (res) {

                inside = !inside;

            }

            if (inside)

                DrawRectange(j, i, 0, 0, fillColor);

        }

    }

    return VOID();

}

 

效果图如下:

本地图片,请重新上传图片

可以发现明显的“漏水”现象。

 

为什么呢?我们将边界图片放大观察,请看大图

本地图片,请重新上传图片

可以看见图中连续的标志像素点。如果其为偶数,就会导致inside在这一边经历两次变换,如果在扫描到边界前是填充,再变换两次,还是填充,就导致了“漏水”现象。

 

为了解决这个问题

引入一个布尔值,flag,初始化为false

flag==true——即使当前点被标记为边界色,也不能改变inside。如果当前点不是边界,则改变flag为false

flag==false——当前点被标记为边界色,则会改变inside。如果当前点不是边界,则会改变inside,且flag变为true

 

改进后的代码如下:

VOID CGraphicDlg::EdgeMarkFill(COLORREF edgeColor, COLORREF fillColor, int yMin, int yMax, int xMin, int xMax)

{

    for (int i = yMin; i <= yMax; i++) {

        bool inside = false;

        bool flag = false;

        for (int j = xMin; j <= xMax; j++) {

            bool res = CheckEdgeMark(j, i, edgeColor);

            if (res && !flag) {

                inside = !inside;

                flag = true;

            }

            else if (!res&&flag) {

                flag = false;

            }

            if (inside&&!res)

                DrawRectange(j, i, 0, 0, fillColor);

        }

    }

    return VOID();

}

 

效果图:

图片

然而顶部密集的部分,还是漏了。至于这个问题,恳请高人指点啊。

最后放上两张放大图


图片

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值