Ironpython中的凸包

问题描述

我正在尝试从点列表中获取凸包,这是基于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]))

“凸包”的输出明显不正确:

Output of "Convex Hull" which is clearly incorrect.

为澄清起见进行编辑:

获得有利于最左边的最低点。 按与x轴的角度对所有其他点进行排序。 将前三个点添加到堆栈中。 循环, 如果下一个排序点将产生顺时针旋转,请移除堆栈顶部。 否则,如果它创建了逆时针旋转,则将候选排序点添加到堆栈顶部。

我将着手整理一个可复制的案子。

YouTube链接带有图形的说明。

Convex Hull Algorithm

所需的输出:

Desired Output:

解决方法

我用python重建了它并使其工作。我认为问题出在我如何计算angleDiff的地方,这样可以更容易地查看叉积z值的符号。

{@ {1}}确实会跳过一个值,谢谢杰森。

在最初的示例中,我也倒退了stack = [p0,points.pop(0),points.pop(1)]。应该是vector1不是 stack[-1] - stack[-2]

stack[-2] - stack[-1]

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...