希尔伯特空间填充曲线(非正方形)任意比例

时间:2015-10-10 19:52:52

标签: geometry computational-geometry feature-extraction

希尔伯特空间/平面填充曲线是否有任何扩展,将非正方形曲面映射到矢量/线[用于图像映射到矢量]?

3 个答案:

答案 0 :(得分:6)

我今天自己就是这样做的。我找到了Lutz Tautenhahn的这个页面:

"Draw A Space-Filling Curve of Arbitrary Size"

该算法没有名称,他没有引用任何其他人,草图表明他自己想出了它。所以,直到有关于这个主题的更多知识的人出现,我们称之为Tautenhahn曲线?对于2的幂,它会变回希尔伯特曲线!

仍然在挖掘凌乱的源代码,不知道Big-O开销等等最终会是什么。

看起来他从上到下将空间划分为“均匀”,所以假设开销不是太大,那么它可能是你想做的事情的好选择。

编辑:虽然我怀疑你这么多年后会看到这个,但我最近发现了2000年的一篇论文,其中另一种方法可能在你的具体案例中有用:

Revital Dafner,Daniel Cohen-Or和Yossi Matias的

"Context-based Space Filling Curves"

这是一种构建空间填充曲线的方法,该曲线对于基础图像数据的变化是“最优的”。

答案 1 :(得分:1)

有自适应希尔伯特曲线,但是它很难用于其他用途,但你可以将“正常”希尔伯特曲线映射到任何矩形。

答案 2 :(得分:0)

我编写了一种算法,可以为2D和3D中任意大小的矩形生成类似希尔伯特的曲线。 55x31的示例:curve55x31

这个想法是递归地应用类似希尔伯特的模板,但是在将域尺寸减半时避免奇数大小。如果尺寸恰好是2的幂,则将生成经典的希尔伯特曲线。

def gilbert2d(x, y, ax, ay, bx, by):
    """
    Generalized Hilbert ('gilbert') space-filling curve for arbitrary-sized
    2D rectangular grids.
    """

    w = abs(ax + ay)
    h = abs(bx + by)

    (dax, day) = (sgn(ax), sgn(ay)) # unit major direction
    (dbx, dby) = (sgn(bx), sgn(by)) # unit orthogonal direction

    if h == 1:
        # trivial row fill
        for i in range(0, w):
            print x, y
            (x, y) = (x + dax, y + day)
        return

    if w == 1:
        # trivial column fill
        for i in range(0, h):
            print x, y
            (x, y) = (x + dbx, y + dby)
        return

    (ax2, ay2) = (ax/2, ay/2)
    (bx2, by2) = (bx/2, by/2)

    w2 = abs(ax2 + ay2)
    h2 = abs(bx2 + by2)

    if 2*w > 3*h:
        if (w2 % 2) and (w > 2):
            # prefer even steps
            (ax2, ay2) = (ax2 + dax, ay2 + day)

        # long case: split in two parts only
        gilbert2d(x, y, ax2, ay2, bx, by)
        gilbert2d(x+ax2, y+ay2, ax-ax2, ay-ay2, bx, by)

    else:
        if (h2 % 2) and (h > 2):
            # prefer even steps
            (bx2, by2) = (bx2 + dbx, by2 + dby)

        # standard case: one step up, one long horizontal, one step down
        gilbert2d(x, y, bx2, by2, ax2, ay2)
        gilbert2d(x+bx2, y+by2, ax, ay, bx-bx2, by-by2)
        gilbert2d(x+(ax-dax)+(bx2-dbx), y+(ay-day)+(by2-dby),
                 -bx2, -by2, -(ax-ax2), -(ay-ay2))

def main():
    width = int(sys.argv[1])
    height = int(sys.argv[2])

    if width >= height:
        gilbert2d(0, 0, width, 0, 0, height)
    else:
        gilbert2d(0, 0, 0, height, width, 0)

可在https://github.com/jakubcerveny/gilbert上获得3D版本和更多文档