【发布时间】:2011-10-13 13:52:27
【问题描述】:
我正在寻找一种在二维中计算 alpha 形状的实现。我正在运行 ubuntu。我更喜欢这个任务的命令行实用程序,但也可以使用 python 库。
在 Google 中,我发现了许多计算 alpha 形状的实现。但他们都没有输出我想要的。作为输入,我有一个二维点列表(例如,文本文件中每行一对浮点数)。作为输出,我想要另一个二维点列表具有相同的比例。
我已经尝试安装 cgal 的最新 python 绑定,但是这些已经有一段时间不支持并且不再在 Ubuntu 11.04 上编译(我也在 Ubuntu 10.04 上尝试过,但没有运气)。 Clustr,由 Aaron Straup Cope 在 flickr 开发的项目也无法在 Ubuntu 11.04 上编译(可能是因为它也与旧的 CGAL 库相关联)。
我还尝试了来自贝尔实验室的 Ken Clarkson 的 this implementation。它几乎输出了我想要的,输出似乎是另一个比例,它把浮点数变成了整数。
我还尝试了dionysus 的python 绑定。这些已编译,但是当我将点列表提供给函数fill_alpha2D_complex(points, f) 时,输出不是我所期望的。它不是二维点的列表,而是似乎是“持久性图”,我不知道这是什么意思。
有人知道这个问题的简单解决方案吗?
更新:我想打印出与 alpha 形状相关联的点,它处于不再连接的边缘。我认为这意味着“给我与最小 alpha 值相关的点,以便连接形状。”
更新我现在知道了如何从Ken Clarkson's implementation 和(或多或少)从dionysus implementation 获得我想要的东西。 Clarkson 的实现是正确的,它只输出点的索引而不是点本身(与酒神相同的故事),我需要正确设置一些可选标志。我写的包装如下。这个解决方案是理想的,因为它产生了一个既连接又不包含孔的 alpha 形状。 Alpha 是自动设置的。另一方面,狄俄尼索斯不会自动发现这个阿尔法值。另外,Clarkson 的实现可以设置为输出形状的 ps 图像(使用 -afps 标志)。要让克拉克森的代码与非古代版本的 GCC 一起编译,您需要按照here 列出的步骤进行操作。以下代码可用作库或独立包装器:
#!/usr/bin/python -O
import sys, os
import subprocess
import tempfile
hull_path = "./hull.exe"
def get_alpha_shape(points):
# Write points to tempfile
tmpfile = tempfile.NamedTemporaryFile(delete=False)
for point in points:
tmpfile.write("%0.7f %0.7f\n" % point)
tmpfile.close()
# Run hull
command = "%s -A -m1000000 -oN < %s" % (hull_path, tmpfile.name)
print >> sys.stderr, "Running command: %s" % command
retcode = subprocess.call(command, shell=True)
if retcode != 0:
print >> sys.stderr, "Warning: bad retcode returned by hull. Retcode value:" % retcode
os.remove(tmpfile.name)
# Parse results
results_file = open("hout-alf")
results_file.next() # skip header
results_indices = [[int(i) for i in line.rstrip().split()] for line in results_file]
# print "results length = %d" % len(results_indices)
results_file.close()
os.remove(results_file.name)
return [(points[i], points[j]) for i,j in results_indices]
if __name__ == "__main__":
points = [tuple([float(i) for i in line.rstrip().split()]) for line in sys.stdin]
for point_i, point_j in get_alpha_shape(points):
sys.stdout.write("%0.7f,%0.7f\t%0.7f,%0.7f\n" % (point_i[0], point_i[1], point_j[0], point_j[1]))
sys.exit(0)
【问题讨论】:
-
一个简单的点列表不能描述一个阿尔法形状,因为它甚至不一定是连接的。
-
我只想要一个漂亮的点云边界。但如果这个描述不够准确,请参阅我在问题中的更新。
-
连接的 alpha 形状可能仍然不是很好,即包含孔。
-
好吧,我更喜欢“漂亮”的形状,但我不精通计算几何的术语,所以我不知道如何描述什么是“漂亮的形状”。但我觉得它具有直观的属性,例如连接,不包含孔等。我也愿意尝试不同的 alpha 值,直到我得到一个“不错”的值。
标签: python linux ubuntu geometry computational-geometry