2012-04-03 20 views
3

私は楕円に最適な線の数を計算しようとしています。所望の誤差マージン(境界からの最小距離)が与えられる。楕円に最適な線を計算する

私の単位円の解はこうして得られました。

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

    return N * r 

そしてradius - |v| < errorまでv = f(u, v, r)を繰り返します。

次に、必要なセグメント数として2^ii)を単純に取ります。 このアルゴリズムはおそらくO(1)であり、楕円(これは私が必要とするもの)では機能しません。

どのように変更できますか? さらに良い方法はありますか?

答えて

3

私は公式化できません楕円を使って作業すると、ちょっと難しいですが、ここでは、次のようになります。

最初 -私はトリグのビットを使用して円のアルゴリズムを強化します。あなたは単位円による角度angleにまたがる弦(線分)を描く場合は、サークルから弦までの最大距離がこのように計算されます。

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

あなたがして図を描く場合(あなたはこれを見ることができます円、コード、およびコードの二等分線)。この公式を反転すると、許容誤差を考慮した角度を計算できます。コードの最初の行は正確な角度を示します。 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) 

および罪を乗じて半径によってCoS値コードのエンドポイントを計算します。

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

主半径はx方向にある場合には:最大および最小半径majorminorの楕円について、私は再び角度を算出する円の式を使用する -

サード

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

これは常にあなたの楕円のための最小限のポリゴンを与えるものではありません(それウィル:マイナー半径がy方向にある、あなたは、このような弦のエンドポイントを計算することができます特に短軸の近くに必要以上のコードがありますが、特に潰れた楕円の場合は)、角度計算を一度行うだけです。実際に和音の数を最小限に抑える必要がある場合は、各和音を描いた後に、各和音の後に角度を再計算する必要があります。式は簡単ではありません( "単純ではない" = "私は把握する ")。

1

円のためのO(1)解があります:等価なセグメントの数を計算して、必要なsagittaを得ることができます。楕円はよりハードケースです。より大きいセミキシス(ほぼ焦点に近い)に垂直なコードの場合、最大のセグジットは、より大きなセミキシスの端でセグメントの接合点を選択することが妥当と思われる(少なくとも最初の近似として)