2013-04-28 92 views
1

我已經閱讀了一切,我可以在這裏找到關於這個主題,但我沒有設法將部分代碼翻譯成簡單的Python我會明白。Python - 均勻分佈貝塞爾曲線上的對象

我得到這個基礎上德卡斯特里奧算法的this very good explanation

def divideCurve(p0, cp0, cp1, p1, t): 
    # p0 and p1 are the start/end points of the bezier curve, 
    # cp0 and cp1 are the control points 
    # all points are tuples of their coordinates: p0 = (10, 15) 

    Ax = ((1 - t) * p0[0]) + (t * cp0[0]) 
    Ay = ((1 - t) * p0[1]) + (t * cp0[1]) 
    Bx = ((1 - t) * cp0[0]) + (t * cp1[0]) 
    By = ((1 - t) * cp0[1]) + (t * cp1[1]) 
    Cx = ((1 - t) * cp1[0]) + (t * p1[0]) 
    Cy = ((1 - t) * cp1[1]) + (t * p1[1]) 

    Dx = ((1 - t) * Ax) + (t * Bx) 
    Dy = ((1 - t) * Ay) + (t * By) 
    Ex = ((1 - t) * Bx) + (t * Cx) 
    Ey = ((1 - t) * By) + (t * Cy) 

    Px = ((1 - t) * Dx) + (t * Ex) 
    Py = ((1 - t) * Dy) + (t * Ey) 

    print Px, Py 

for T in range(0, 11, 1): 
    t = T*0.1 
    divideCurve(p0, cp0, cp1, p1, t) 

但這沿曲線分佈不均的點。

我認爲here是一個可能的解決方案,但我完全不明白弧長函數的反函數或如何將其轉換爲python的代碼。 我發現另一種方法here,我認爲它採取了不同的方法,我再也不明白在python中實現的足夠了。

如果有人願意澄清這個簡單的python,那會很棒。

回答

2

開始:這是一個沒有象徵性的解決方案的問題,即你可以不坐「長換T」功能(在值...,曲線的長度爲X)的貝塞爾曲線並將其反轉,以便得到「長度爲t」(如果我的長度是總長度X的百分之...,那麼我的值就是t)。因此,所有,你會發現這種情況的實現是對主題的變化

  1. 確定全曲線長度,
  2. 確定沿曲線各種值參考長度,並
  3. 的值,唐完全匹配參考值,找到它附近的兩個值,並進行插值。

某些實現會將此曲線變平(將貝塞爾曲線變成一系列直線),其他實現將構造距離查找表(LUT)。一些實現將在已知參考值之間進行線性插值(有效模擬平坦曲線),其他實現將使用圓弧插值,將兩個已知值之間的每個段逼近爲(圓形)弧的一部分。對於所有這些實施,底線是您的里程將根據所做的選擇而有所不同,但所有這些都會接近「實際」結果,您將連續的t值之間的距離設置得越小。

最簡單的,並且通常是最快的,是構造一個LUT具有連續值之間的「足夠小」步長,再也不與插打擾,而不是挑選最接近實際點長度。只要stepize導致1px或更低的段長度,出於顯示目的,你不需要任何更好的東西,因爲更高的分辨率實際上不會導致「更好」的點,它們將在同一像素上如果你讓你的距離參考點更精確。

我對此有一個描述,代碼是http://pomax.github.io/bezierinfo/#tracing,它在Processing中,而不是python中,但Processing是一種非常簡單的語言,並且給出了算法描述,它應該是相對簡單的,直接寫入Python基於你已有的代碼。