【问题标题】:Hilbert space filling curve for (non-square) arbitrary proportions(非方形)任意比例的希尔伯特空间填充曲线
【发布时间】:2019-10-29 16:27:48
【问题描述】:

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

【问题讨论】:

  • 是的,但需要过采样或欠采样以适应新维度。但我想避免使用这种曲线。

标签: geometry computational-geometry feature-extraction


【解决方案1】:

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

"Draw A Space-Filling Curve of Arbitrary Size"

该算法没有名称,他没有引用任何其他人,并且草图表明他自己想出了它。因此,直到出现对该主题有更多了解的人之前,我们将其称为 Tautenhahn 曲线?但是,对于 2 的幂,它又会变成希尔伯特曲线!

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

看起来他从上到下尽可能“均匀”地划分空间,所以假设开销不是太大,它可能是你想做的一个很好的候选。

编辑:虽然我怀疑这么多年后你会看到这一点,但我最近发现了一篇 2000 年的论文,其中的另一种方法可能实际上对你的具体情况有用:

"Context-based Space Filling Curves" 由 Revital Dafner、Daniel Cohen-Or 和 Yossi Matias 撰写

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

【讨论】:

  • 虽然这可能会回答问题,但最好在此处提供实际信息而不仅仅是链接。 Link-only answers are not considered good answers and will probably be deleted.
  • 我明白这一点,但问题是我自己还没有完全弄清楚它是如何工作的。演示的源代码写得很糟糕,解释是对纸上草图证明的扫描。我正在努力,但认为其他人可能比我更快地解决这个问题,所以我分享了这个链接,意思是“答案就在这里,也许你可以打败我来解密这个。”跨度>
  • @Job:我试过 40x45,它也可以。惊人的发现!你解密了吗?
  • 这个算法肯定会产生漂亮的曲线,这正是我正在寻找的——我也焦急地等待着有人找出它记录不佳的魔法酱......
【解决方案2】:

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

这个想法是递归地应用类似 Hilbert 的模板,但在将域维度减半时避免出现奇怪的大小。如果维度恰好是 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 版本和更多文档

【讨论】:

    【解决方案3】:

    有自适应希尔伯特曲线,但在 imo 中,它非常困难并且可用于其他用途,但您也可以将“正常”希尔伯特曲线映射到任何矩形。

    【讨论】:

    • 它是怎么做的?我找不到任何非方形示例或教程。
    • 您可以将坐标视为二进制并交错。然后将其视为基数为 4 的数字。这是一条 z 阶曲线。与希尔伯特曲线类似!
    猜你喜欢
    • 2021-03-16
    • 1970-01-01
    • 2016-06-19
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2019-04-14
    相关资源
    最近更新 更多