我有一个1 * 1多边形的集合,每个多边形由其边界(一组四个点)定义,我在我的代码示例中使用下面的函数 area()来创建这些。我希望将这些相邻的正方形组合成一个多边形,该多边形也根据其边界点定义。
我希望以强力的方式做到这一点,我首先添加两个相邻的1 * 1方块,使用下面的函数 join()创建一个更大的多边形,并按此顺序继续生长多边形。所以join的第一个参数是到目前为止的多边形,第二个参数是一个adjecent 1 * 1 square,我希望将其添加到多边形中。返回值是新多边形的边界,当前与新的1 * 1连接。
这是我到目前为止所得到的:
def join(current, new):
""" current is the polygon, new the 1*1 square being added to it"""
return get_non_touching_part_of_boundary(current, new) + get_non_touching_part_of_boundary(new, current)
def get_non_touching_part_of_boundary(this, other):
for i,point in enumerate(this):
if point not in other and this[i-1] in other:
break # start of non touching boundary from a clockwise perspective
non_touching_part_of_boundary = []
for point in this[i:] + this[:i]:
if not point in other:
non_touching_part_of_boundary.append(point)
return non_touching_part_of_boundary
def area(point):
""" boundary defined in a clockwise fashion """
return [point,(point[0],point[1]+1),(point[0]+1,point[1]+1),(point[0]+1,point[1])]
a = area((0,1)) # a assigned a 1*1 polygon
a = join(a, area((0,2))) # a assigned a 2*1 polygon
a = join(a, area((1,2)))
a = join(a, area((2,2)))
a = join(a, area((2,1)))
a = join(a, area((2,0)))
print(a)
这给了我以下多边形形状(数字表示其组成方块的添加顺序):
234
1 5
6
上面代码的打印输出给出:
[(2, 2), (1, 2), (1, 1), (0, 1), (0, 3), (3, 3), (3, 0), (2, 0)]
这是定义多边形边界所需的最小点数。
但是如果我通过 a = join(a,area((1,0)))再向这个形状添加一个方块,从而创建一个洞,我的算法就会崩溃:
234
1 5
76
这是我的算法无法处理的另一个多边形:
123
64
5
任何人都可以帮助我吗?我希望多边形中的孔列在单独的列表中。
感谢!
答案 0 :(得分:2)
我认为您的算法很难修复。考虑到例如向多边形添加单个方块可能会创建多个孔:
xxx
x x
xxx xxx
x y x
xxx xxx
x x
xxx
想象一下,例如,所有x
都是“当前多边形”,然后你和y
...
通常,闭合区域由闭环集合定义,您只能使用单个列表,而只需使用更复杂的方法在循环之间创建零区域桥接。对我看来你正在寻找的东西的简单方法是截然不同的:
如果您正确收集数据并假设您可以在数据周围添加一个“out”单元格的边框,那么可以保证您将得到一个零或多个闭环的列表,因为每个点都会列出一个偶数墙壁。
这些循环(当考虑奇数均匀填充规则时)将定义您的初始区域。请注意,您可能会获得自相交循环...如果您想避免算法稍微复杂一点。
此方法也比一次处理一个边界并执行所有这些合并操作要快得多,结果将是一般的(包括非连接区域和孔)。
以下图像是a complete implementation of this algorithm的结果,包括在循环收集期间的右转逻辑,以避免自相交循环。已经为输出多边形分配了不同的颜色,并且已经切割了角以使转弯变得明显。