洪水填充三维多边形

ste*_*tef 5 c++ math polygon flood-fill computational-geometry

这是给你的问题;)

我有一个填充1和0的三维数组.1代表3维复杂多边形(不是简单的多边形).只有多边形的边界值为1,内部填充0.现在问题是:

我需要一个快速算法来填充这些多边形1s.阵列的尺寸通常约为.512x512x100.

提前致谢!

这是2d中的一个例子:

0000111110000
0000100010000
0000100010000
0000111110000

应该导致

0000111110000
0000111110000
0000111110000
0000111110000


这是@Mikolas算法的正确三维解决方案吗?

    void scan_polygon(int frames, int rows, int cols, char data[][][], char result[][][]){
for(int f=0; f < frames; ++f)
for(int r=0; r<rows; ++r)
for(int s = 0, c=0; c<cols-1; ++c)
{
    s ^= s ? ( data[f][r][c] && !data[f][r][c+1]) :
             (!data[f][r][c] &&  data[f][r][c-1]);

    result[f][r][c] = s;
}

for(int f=0; f < frames; ++f)
for(int c=0; c<cols; ++c)
for(int s = 0, r=0; r<rows-1; ++r)
{
    s ^= s ? ( data[f][r][c] && !data[f][r+1][c]) :
             (!data[f][r][c] &&  data[f][r-1][c]);

    result[f][r][c] &= s;
}
Run Code Online (Sandbox Code Playgroud)

}

最好的祝福,

STEF

Mik*_*ola 3

如果您假设多边形是流形的,则可以在单个 for 循环中完成此操作。只需从左上​​角开始,并在越过边缘时跟踪奇偶校验。

一个简单的 2D 版本(添加了转置情况):

void scan_polygon(int rows, int cols, char** data, char** result)
{
    for(int r=0; r<rows; ++r)
    for(int s = 0, c=0; c<cols-1; ++c)
    {
        s ^= s ? ( data[r][c] && !data[r][c+1]) :
                 (!data[r][c] &&  data[r][c-1]);

        result[r][c] = s;
    }


    for(int c=0; c<cols; ++c)
    for(int s = 0, r=0; r<rows-1; ++r)
    {
        s ^= s ? ( data[r][c] && !data[r+1][c]) :
                 (!data[r][c] &&  data[r-1][c]);

        result[r][c] &= s;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您有一个悬空像素或沿扫描线伸出的边缘,则可能会出现这种情况,例如:

00000000000000000000        
00000000*11111111111   <--- Whoops!
000000*111*000000000
00000*11111*00000000
Run Code Online (Sandbox Code Playgroud)

要解决此问题,您只需在转置数组上重复该过程,然后将所有结果“与”在一起即可。Sud 等人使用类似的方法在 GPU 上对网格进行体素化。它并不是完美无缺的,因为您可以配置多个非流形顶点,其中它们的噪声锥体相交,但如果您可以保证这种情况不会发生(或者如果它很少发生),那么它就是其中之一我所知道的最简单的方法可以快速获得结果。

编辑:修改解决方案以显示如何在进行迭代后将数组重新组合在一起。