【问题标题】:integer winding number algorithm with edge cases具有边缘情况的整数绕组数算法
【发布时间】:2012-01-17 03:13:26
【问题描述】:

我想要关于一个点的封闭分段线性路径(例如多边形)的winding number,但此外,我想检测路径何时通过该点。出于这个原因,我将标准绕组数加倍。对于逆时针方向的非相交多边形,该值为:

  • 0 如果点在多边形之外
  • 如果点在多边形的边或顶点上,则为 1
  • 2 如果点在多边形内部

在其他情况下也是如此。 (编辑:image of a few examples

当点位于边或顶点时,我发现的每个算法都会失败。

我的另一个要求是,当所有输入(即点的坐标和路径的顶点)都是整数时,它必须给出完全正确的结果。所以这几乎排除了三角函数或平方根,并且必须小心使用除法。

我确实不需要处理具有两个连续重合点或 180 度转弯的退化路径。

无论如何,我想我有一个解决方案。但是,它似乎有点不雅,我不确定它是否正确。 (当点位于顶点时,我真的很困惑自己会发生什么。)这是在 python 中:

def orient((x,y), (a0,b0), (a1,b1)):
    return cmp((a1-a0)*y + (b0-b1)*x + a0*b1-a1*b0, 0)
def windingnumber(p0, ps):
    w, h = 0, [cmp(p, p0) for p in ps]
    for j in range(len(ps)):
        i, k = (j-1)%len(ps), (j+1)%len(ps)
        if h[j] * h[k] == -1:
            w += orient(p0, ps[j], ps[k])
        elif h[j] == 0 and h[i] == h[k]:
            w += orient(ps[k], ps[i], ps[j])
    return w

Link to a version with comments and unit tests.

我想要一个正确算法的链接,或者我的算法正确的一些确认,或者我的算法失败的测试用例。谢谢!

【问题讨论】:

    标签: python algorithm math geometry computational-geometry


    【解决方案1】:

    问题是你的假设是错误的。

    没有为轮廓上的点定义缠绕数。 (特别是积分没有很好的定义)。

    如果你两次走同一条路,你会得到两倍的绕组数。因此,如果您假设如果点在计数上,数字将为 1 是正确的,那么这实际上意味着如果您去一次,则绕组数是 1/2,但这显然是错误的,因为绕组数总是一个整数。

    【讨论】:

    • 哦,是的,你完全正确,我想要的数字更恰当地是通常定义的绕组数的扩展。我认为这是一个非常直观且一致的扩展,但是是的,这不是正常的定义。也许我应该用不同的名字来称呼它。
    • 除了,我在这里没有看到定义......如果点在轮廓上,它总是 1。这根本不一致。如果曲线通过该点然后绕它绕 10 次会怎样。还是 1...跨度>
    • 哦,好吧,对不起,我认为定义会很明显,虽然有点难以说明。如果两条边通过该点,则该点的“修改”绕组数将为 2(假设它不在其他任何东西内)。下面是几个不同值的说明:imgur.com/cDc6o
    • 我仍然不清楚当你把它当成 +1 和当 -1... 关于缠绕数的事情是它允许你只使用本地信息来计算它(微分角度),然后整合它。我不明白您将如何仅使用本地信息来确定符号 +1/-1。
    • 好吧,我对等高线积分的定义不是熟悉,但我的想法是,如果你从你的位置,然后转身面对它,直到它回到你身边,然后如果你逆时针转180度,它是+1,如果你已经转了180度,它是-1。无论如何,如果您认为这是一个不好的定义,那很好,不要为此烦恼。我当然不是建议人们采用它,我只是想要它自己!
    猜你喜欢
    • 2016-10-08
    • 2017-05-26
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多