闭合轮廓绕组数的算法
Posted
技术标签:
【中文标题】闭合轮廓绕组数的算法【英文标题】:Algorithm for the Winding Number of a Closed Contour 【发布时间】:2015-10-20 21:52:57 【问题描述】:假设我有一个由x(p)
和y(p)
两个函数定义的轮廓形状,其中p
是沿形状周边行进的距离,在0
和1
之间进行归一化。例如,关于原点的单位圆将定义为x(p) = sin(2 * pi * p)
和y(p) = cos(2 * pi * p)
。
确定一个点是否在该圆内的简单测试是计算该点与原点的距离,然后检测该距离是否小于或等于1
。
但是如果我的形状有多个交叉点,并且比圆形复杂得多,该怎么办?
对于由一组点定义的离散形状存在point in polygon 测试。该算法很容易找到,因为它在很多地方都使用过。但是,如果我不想使用形状的离散定义,我可以使用什么算法来确定绕组数,假设形状是在编译时定义的?
【问题讨论】:
***有帮助吗? en.wikipedia.org/wiki/Winding_number @MarkRansom 我看到了,我希望它可以用 CS 术语而不是应用数学术语来解释。有离散算法的定义,但就微分几何而言,您在实现它时有点靠自己。 我看到的唯一代码是针对离散段的,你的代码是一种特殊情况。 【参考方案1】:在多边形测试中推广该点,您可以找到y(p)=0
的所有解,使得x(p)>0
并使用它们的数字的奇偶性。
在圆圈的情况下,cos(2πp)=0
对应于p=(k+1/2)π
,并且[0,1)
范围内只有一个值p
对应于sin(2πp)>0
。
到目前为止,如果您能解析解出y
方程,那就太好了。否则,您将需要一个可靠的数值求解器,能够找出所有根。另一种方法是使曲线变平(将其绘制为折线,确保最大偏差容限),然后应用多边形算法。
为了第二个例子,让我们考虑一下 Pascal 的 limaçon,方程为 r = 0.5 + cos Θ
,以及沿 X
的一些测试点。
y = (0.5 + cos Θ) sin Θ = 0
对于Θ=0
、2π/3
、π
、4π/3
。对应的横坐标为1.5
、0
、0.5
和0
。
您可以得出结论,X 轴上的内部点介于 0.5
和 1.5
之间(也位于 0
,以退化的方式)。
【讨论】:
第一个建议是我尝试做的,最后我得到了一个正方形,哈哈。根据您的第二个建议,我还认为将曲线“渲染”为一组点会起作用。我将再次尝试第一种方法,看看它对我有什么好处。 @NmdMystery:让我补充一点,如果方程 y=0 无法解析求解,您仍然可以找到一条通过原点的曲线 F(x, y)=0 (x(0=0, y(0)= 0, F(0, 0)=0) 并且延伸得足够远,你可以表达根。【参考方案2】:如果您知道形状内部(或外部)的一个点并且该形状是平滑且不相交的,那么您可以将已知点连接到任何其他点并计算它穿过边界的次数。偶数次意味着未知点同样位于内部(或外部)。奇数表示相反。
这是基于乔丹曲线定理。我记得,证明定理需要缠绕数,但应用很简单。
【讨论】:
如果形状相交,并且有区域的绕组数大于 1,该怎么办? @NmdMystery 。 . .乔丹曲线定理适用于平滑(实际上,我认为是连续的)非相交曲线。如果它们相交,那么您需要将形状分成单独的形状。【参考方案3】:如何计算闭合曲线的总曲率(假设它处处可微),然后除以 2PI?请参阅 Wiki 的总曲率页面 here。
【讨论】:
以上是关于闭合轮廓绕组数的算法的主要内容,如果未能解决你的问题,请参考以下文章