2012-05-28 44 views
1

我目前正在嘗試實現繪製貝塞爾曲線的Cox De Boor算法。我已經設法生成一些可以接受的東西,一定數量的控制點和一個預定義的結矢量,但是我想調整我的代碼,使它能夠在給定任意數量的控制點和任何程度的情況下運行。我90%確定我目前遇到的問題,即路徑徘徊到0/0,是由於我沒有正確計算結矢量。如果有人能給我一兩個提示,我會很感激。請注意,我正在單獨計算每個維度(本例中只是x和y);我最終會調整這些代碼,對所有維度使用相同的預先計算。我也可以調整它來使用C數組而不是NSArrays,但從我所見到的情況來看,這樣做並沒有真正的速度優勢。計算Cox De Boor算法的結矢量的正確方法是什麼?

我目前正在使用5個控制點和{0,0,0,0,1,2,2,2,2}結矢量生成3級曲線。

- (double) coxDeBoorForDegree:(NSUInteger)degree span:(NSUInteger)span travel:(double)travel knotVector:(NSArray *)vector 
{ 
    double k1 = [[vector objectAtIndex:span] doubleValue]; 
    double k2 = [[vector objectAtIndex:span+1] doubleValue]; 
    if (degree == 1) { 
     if (k1 <= travel && travel <= k2) return 1.0; 
     return 0.0; 
    } 

    double k3 = [[vector objectAtIndex:span+degree-1] doubleValue]; 
    double k4 = [[vector objectAtIndex:span+degree] doubleValue]; 
    double density1 = k3 - k1; 
    double density2 = k4 - k2; 
    double equation1 = 0.0, equation2 = 0.0; 

    if (density1 > 0.0) equation1 = ((travel-k1)/density1) * [self coxDeBoorForDegree:degree-1 span:span travel:travel knotVector:vector]; 
    if (density2 > 0.0) equation2 = ((k4-travel)/density2) * [self coxDeBoorForDegree:degree-1 span:span+1 travel:travel knotVector:vector]; 

    return equation1 + equation2; 
} 



- (double) valueAtTravel:(double)travel degree:(NSUInteger)degree points:(NSArray *)points knotVector:(NSArray *)vector 
{ 
    double total = 0.0; 
    for (NSUInteger i = 0; i < points.count; i++) { 
     float weight = [self coxDeBoorForDegree:degree+1 span:i travel:travel knotVector:vector]; 
     if (weight > 0.001) total += weight * [[points objectAtIndex:i] doubleValue]; 
    } 
    return total; 
} 

回答

0

沒關係,我發現這個非常有用的網頁: http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/INT-APP/PARA-knot-generation.html

因此任何人同樣的問題可以使用以下方法來生成一個合適的節點向量,其中「對照」是控制的數影響線段的點數和'度'是......好,曲線的程度!不要忘記,程度不能等於或超過曲線中控制點的數量:

- (NSArray *) nodeVectorForControlCount:(NSUInteger)controls degree:(NSUInteger)degree 
{  
    NSUInteger knotIncrement = 0; 
    NSUInteger knotsRequired = controls + degree + 1; 
    NSMutableArray *constructor = [[NSMutableArray alloc] initWithCapacity:knotsRequired]; 
    for (NSUInteger i = 0; i < knotsRequired; i++) { 
     [constructor addObject:[NSNumber numberWithDouble:(double)knotIncrement]]; 
     if (i >= degree && i < controls) knotIncrement++; 
    } 

    NSArray * returnArray = [NSArray arrayWithArray:constructor]; 
    [constructor release]; 
    return returnArray;  
} 
相關問題