a working non-recursive floodfill algorithm written in C?

后端 未结 12 2228
日久生厌
日久生厌 2020-12-02 23:39

I\'ve been trying to find a working floodfill algorithm. Of the many algorithms I\'ve tried only the \'recursive line fill\' one behaves exactly as it should with the major

12条回答
  •  春和景丽
    2020-12-03 00:12

    Here's some C++ code that does what you want. It uses a queue, and is more efficient about insertions into the queue.

    connectedRegion(const Point& source, RegionType& region, const Color target)
    {
        Color src_color = color_of(source, region);
        if (region.count(source) == 0 || src_color == target)
            return;
        std::queue analyze_queue;
        analyze_queue.push(source);
    
        while (!analyze_queue.empty())
        {
            if (color_of(analyze_queue.front()) != src_color)
            {
                analyze_queue.pop();
                continue;
            }
            Point leftmost_pt = analyze_queue.front();
                leftmost_pt.col -= 1;
            analyze_queue.pop();
            Point rightmost_pt = leftmost_pt;
                rightmost_pt.col += 2;
            while (color_of(leftmost_pt, region) == src_color)
                --leftmost_pt.col;
    
            while (color_of(rightmost_pt, region) == src_color)
                ++rightmost_pt.col;
    
            bool check_above = true;
            bool check_below = true;
                Point pt = leftmost_pt;
                ++pt.col;
            for (; pt.col < rightmost_pt.col; ++pt.col)
            {
                set_color(pt, region, target);
    
                Point pt_above = pt;
                        --pt_above.row;
                if (check_above)
                {
                    if (color_of(pt_above, region) == src_color)
                    {
                        analyze_queue.push(pt_above);
                        check_above = false;
                    }
                }
                else // !check_above
                {
                    check_above = (color_of(pt_above, region) != src_color);
                }
    
                Point pt_below = pt;
                        ++pt_below.row;
                if (check_below)
                {
                    if (color_of(pt_below, region) == src_color)
                    {
                        analyze_queue.push(pt_below);
                        check_below = false;
                    }
                }
                else // !check_below
                {
                    check_below = (color_of(pt_below, region) != src_color);
                }
            } // for 
        } // while queue not empty
        return connected;
    }
    

提交回复
热议问题