【发布时间】:2020-08-12 22:45:29
【问题描述】:
我正在尝试从点列表中获取凸包,这是基于 Graham Scan 方法的。
points = []
for element in elements:
#getpoints function returns four corners of element bounding box with z overwritten to 0 so that we are working in 2D coordinates.
for p in getPoints(element):
points.append(p)
p0 = None
points.sort(key=lambda x: x.X)
points.sort(key=lambda x: x.Y)
#isolate lower left point
p0 = points.pop(0)
#sort by angle to x axis
points.sort(key=lambda x: DB.XYZ.BasisX.AngleTo(x-p0))
# We know the second point is correct, we are starting by checking the third point.
stack = [p0, points.pop(0), points.pop(1)]
while len(points) > 0:
vector1 = stack[-2] - stack[-1]
vector2 = points[0] - stack[-1]
angle1 = math.atan2(vector1.X, vector1.Y)
angle2 = math.atan2(vector2.X, vector2.Y)
angleDiff = angle1 - angle2
if angleDiff >= 0:
stack.pop(-1)
######stack.append(points.pop(0)) I don't think this is needed, but it doesn't solve my problem when removed.
else:
stack.append(points.pop(0))
curves = []
for i, point in enumerate(stack):
curves.append(DB.Line.CreateBound(point, stack[i-1]))
“凸壳”的输出明显不正确:
编辑澄清:
获取最左边的最低点。 按与 x 轴的角度对所有其他点进行排序。 将前三个点添加到堆栈中。 环形, 如果下一个排序点将创建顺时针旋转,则删除堆栈的顶部。 否则,如果它创建逆时针旋转,则将候选排序点添加到堆栈顶部。
我会努力整理一个可重现的案例。
YouTube 链接到图片说明。
期望的输出:
【问题讨论】:
-
那么...问题是什么?
-
stack = [p0, points.pop(0), points.pop(1)]似乎不对;您正在跳过一个点,即在此语句之前位于points[1]的点(pop(0)将该点移动到索引 0,pop(1)然后在索引 2 处获取该点)。 -
请提供预期的minimal, reproducible example。显示中间结果与您的预期不同的地方。支持图很有帮助,但请提供一个简单失败示例,跟踪您的错误点,并将输出作为点列表提供给我们。
-
请添加一些说明问题的简单测试数据。
-
澄清:包括一些证明意外行为的有效数据。数据应采用某种格式,以便某人(仅使用您的帖子内容)能够将其用作程序的输入,并产生相同的输出。此外,您的程序应该无需任何进一步修改即可运行(现在它无法运行)。
标签: python ironpython convex-hull