计算椭圆的最佳拟合线

时间:2012-04-03 01:07:44

标签: python math geometry

我试图计算最适合椭圆的线数;给定所需的误差范围(距边界的最小距离)。

因此我的单位圈解决方案就是这样。

def f(u, v, r):
    mid_uv = (u + v) * 0.5
    N = normalized(mid_uv)

    return N * r

重复v = f(u, v, r)直到radius - |v| < error

然后简单地将2^ii作为迭代次数)作为所需的段数。 这个算法可能是O(1),并不适用于省略号(我需要它)。

我该如何适应它? 或者更好的是,还有另一种解决方案吗?

2 个答案:

答案 0 :(得分:3)

我无法形成一个很好的答案 - 使用省略号对圈子来说更具挑战性 - 但是这里有步骤:

首先 - 我会通过使用一点trig来收紧圆圈的算法。如果您绘制一个跨越角度angle通过单位圆的和弦(线段),则计算从圆到弦的最大距离:

error = 1 - math.cos( angle / 2 )

(如果您使用圆,弦和弦的平分线绘制图表,则可以看到此情况。)反转此公式,您可以计算给定容许误差的角度。第一行代码给出了精确的角度;如果需要,第二行会缩小角度,使其成为整个圆的精确分数。

angle = 2 * math.acos( 1 - error )
angle = (2*math.pi) / math.ceil( (2*math.pi) / angle )

一旦你有角度,就可以很容易地计算和弦终点的单位圆周围的点数:[(1,0), (cos(angle),sin(angle)), cos(2*angle),sin(2*angle)), ... ]。你最终会得到一个正多边形。

第二个 - 对于半径为radius的圆,运行上述公式,调整如下:

angle = 2 * math.acos( 1 - error/radius )
angle = (2*math.pi) / math.ceil( (2*math.pi) / angle )

通过将sin和cos值乘以半径来计算和弦终点。

第三 - 对于具有最大和最小半径majorminor的椭圆,我会使用圆公式再次计算角度:

radius = max( major, minor )
angle = 2 * math.acos( 1 - error/radius )
angle = (2*math.pi) / math.ceil( (2*math.pi) / angle )

如果主半径在x方向而小半径在y方向,那么你可以像这样计算和弦终点:

[ (major, 0),
  (major*cos(angle), minor*sin(angle)),
  (major*cos(2*angle), minor*sin(2*angle)),
  ... ]

这并不总是为您提供椭圆的最小多边形(它将在短轴附近有更多的和弦,特别是对于非常宽的椭圆),但您只需要进行一次角度计算。如果你真的需要最小化和弦的数量,那么在绘制每个和弦之后,你需要在每个和弦之后重新计算角度,并且公式不是直接的(其中“不直接”=“难以我想弄清楚“)。

答案 1 :(得分:1)

圆圈有O(1)解:您可以计算相等段数,以获得所需的sagitta。椭圆是更难的情况。对于与较大半轴(近焦点)垂直的弦而言,最大矢量将是合理的,因此在较大半轴的末端选择段的连接点似乎是合理的(至少 - 作为第一近似值)