zoukankan      html  css  js  c++  java
  • 图形区域填充算法

    在一副图片中填充一块封闭区域功能

    一般采用种子法+递归。

    简单说,就点像素点的周围4个点拿去计算和判断边界。

    但是用递归实现的话,很容易就栈溢出了。

    此时解决的办法,就是用栈+循环  (我比喻为 烧柴火,添柴火模式)

    下面是实现代码

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include <stack>
    #include <queue>
    using namespace std;
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
        this->DoubleBuffered = true;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Image1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
        TColor colorSource = Image1->Canvas->Pixels[X][Y];
        TColor colorDesc = clGreen;
        fillLoop(colorSource,colorDesc,X,Y);
    }
    //---------------------------------------------------------------------------
    //这种递归的写法容易引发溢出
    void TForm1::fill(TColor colorSource,TColor colorDesc,int X,int Y)
    {
        if (X < 0 || X > Image1->Width)
        {
            return;
        }
    
        if (Y < 0 || Y > Image1->Height)
        {
            return;
        }
    
        if (Image1->Canvas->Pixels[X][Y] == colorDesc)
        {
            return;
        }
    
    
        if (Image1->Canvas->Pixels[X][Y] == colorSource)
        {
            Image1->Canvas->Pixels[X][Y] = colorDesc;
    
            TPoint p1(X-1,Y);
            TPoint p2(X,Y-1);
            TPoint p3(X+1,Y);
            TPoint p4(X,Y+1);
    
            fill(colorSource,colorDesc,p1.x,p1.y);
            fill(colorSource,colorDesc,p2.x,p2.y);
            fill(colorSource,colorDesc,p3.x,p3.y);
            fill(colorSource,colorDesc,p4.x,p4.y);
        }
    }
    
    //这是用栈+循环的方法
    void TForm1::fillLoop(TColor colorSource,TColor colorDesc,int X,int Y)
    {
        queue<TPoint> points;
        points.push(TPoint(X,Y));
    
        while (points.size() > 0)
        {
            TPoint p = points.front();
            points.pop();
            TColor color = Image1->Canvas->Pixels[p.x][p.y];
            if (color == colorDesc)
            {
                continue;
            }
            Application->ProcessMessages();
            Image1->Canvas->Pixels[p.x][p.y] = colorDesc;
            TPoint ps[4] = {TPoint(p.x-1,p.y),TPoint(p.x+1,p.y),TPoint(p.x,p.y-1),TPoint(p.x,p.y+1)};
            for (int i = 0 ;i < 4 ; i++)
            {
                if (Image1->Canvas->Pixels[ps[i].x][ps[i].y]
                    == colorSource)
                {
                    points.push(ps[i]);
                }
            }
        }
    }

    关于循环递归的问题

    看这里

    http://www.cnblogs.com/wb-DarkHorse/p/3284228.html

  • 相关阅读:
    企业如何才能“勾搭”上服务网格技术?
    行云创新:云原生加速企业释放数据价值
    行云创新:后疫情时代,云原生为酒店数字化转型破局
    行云创新CEO马洪喜荣获“2021杰出质造人物奖”
    SolarMesh发布 v1.6.1版本,再不来体验就......
    什么是云原生?如何建设云原生平台?
    行云创新联合上汽乘用车打造云原生技术平台,加快实现数字化转型
    五分钟搭建你的第一个区块链应用
    mysql 存储过程
    MySQL-binlog日志格式 binlog_format三种模式详解
  • 原文地址:https://www.cnblogs.com/songr/p/5773133.html
Copyright © 2011-2022 走看看