【问题标题】:Flood Fill scan line洪水填充扫描线
【发布时间】:2014-05-08 07:30:45
【问题描述】:

我写了一个经典的队列floodfill:

public static void floodFill(int y, int x, byte originalvalue, byte newvalue, byte[][] arr) {
    Deque queue = new ArrayDeque();
    queue.add(new int[]{y, x});
    while (!queue.isEmpty()) {
        int[] t = (int[]) queue.poll();
        y = t[0];
        x = t[1];
        if (arr[y][x] == originalvalue) {
            arr[y][x] = newvalue;
            for (int i = 0; i < 8; i++) {
                if (x + dx[i] < arr[0].length && y + dy[i] < arr.length && x + dx[i] > -1 && y + dy[i] > -1 && arr[y + dy[i]][x + dx[i]] == originalvalue) {
                    queue.add(new int[]{y + dy[i], x + dx[i]});
                }
            }
        }
    }
}

现在我想写扫描线Flood Fill,这要快得多。找不到伪代码,看不懂this code

你能帮我优化我的洪水填充或写第一行扫描吗?

我称这种填充方式为大小为 1000-2000 x 1000-2000(不一定是正方形)的字节数组,大区域一次,然后大约 1000 到 1,000,000 次小区域。

【问题讨论】:

  • 扫描线,不是天际线!
  • @YvesDaoust 谢谢你,我的错。
  • 这解释了为什么你没有找到这个算法的痕迹。但请注意,此名称包含两件事:多边形的扫描线填充(称为顶点序列)和扫描线种子填充(区域内)。

标签: java algorithm flood-fill


【解决方案1】:

这是一种改进的洪水填充算法。不是先填充一个像素,然后再填充它的邻居,而是先填充整个水平“运行”像素,然后再填充它的邻居。

递归如下:

Fill(X0, X1, Y, Old, New)

# Precondition: the segment [X0 X1]/Y has the old color and can't be lengthened

查找所有已连接的运行[X0' X1'] 行中的Y-1 具有旧颜色和Fill(X0', X1', Y-1, Old, New)

查找所有已连接的运行 [X0' X1'] 行中的 Y+1 具有旧颜色和 Fill(X0', X1', Y+1, Old, New)

要在新行中查找所有连接的运行,请从 X0 开始,只要您在旧像素上就向左移动,或者只要您在非旧像素上就向右移动(停在 @987654330 @);你有X0'。然后在旧像素上继续向右;你有X1'。只要X0'[X0 X1] 中,就重复向右搜索。

一些实施细节取决于您选择的 4/8 连接规则。

【讨论】:

  • 不要依赖于会考虑“因为我从 Y 行来查找 Y+1 行中的运行,我不需要再次比较 Y+1 和 Y 行”的优化。跨度>
猜你喜欢
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
  • 2013-01-16
相关资源
最近更新 更多