2012-04-03 114 views
3

我正在嘗試計算最適合橢圓的線條的數量;給定所需的誤差範圍(離邊界的最小距離)。計算最適合橢圓的線條

因此,我的單位圓的解決方案。

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),並不適用於橢圓(這是我需要的)。

我該如何適應它?或者更好,還有其他解決方案嗎?

回答

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) 

而受到正弦相乘和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)), 
    ... ] 

這並不總是給你最小的多邊形爲橢圓(該宏將會l在短軸附近有更多的弦杆,特別是對於非常壓扁的橢圓),但是你只需要進行一次角度計算。如果你真的需要減少和絃的數量,那麼在繪製每個和絃之後,需要在每個和絃之後重新計算角度,並且公式不是直接的(其中「不是直接的」=「困難的我想出來「)。

1

有O(1)圈解決方案:你可以計算相等的段數,以獲得需要sagitta。 Ellipse更加困難。對於與較大半軸垂直的絃線(靠近焦點),最大弧度將是最大的,因此選擇較大半軸線末端的線段連接點似乎是合理的(至少 - 如第一次近似)