2013-04-11 3 views
9

Ich habe mehrere Wochen daran gearbeitet, aber ich konnte meinen Algorithmus nicht richtig arbeiten lassen und ich bin am Ende meiner Weisheit. Hier ist ein Beispiel dafür, was ich erreicht habe:De Boors-Algorithmus zum Finden von Punkten auf einem B-Spline implementiert

enter image description here

Wenn alles arbeitet ich am Ende einen perfekten Kreis/Oval erwarten.

Meine Beispielpunkte (in weiß) werden jedes Mal neu berechnet, wenn ein neuer Kontrollpunkt (in gelb) hinzugefügt wird. An 4 Kontrollpunkten sieht alles perfekt aus, wieder da ich ein 5. über die ersten Sachen addiere, sieht es gut aus, aber dann am 6. beginnt es zu der Seite zu gehen und am 7. springt es zum Ursprung auf!

Im Folgenden werde ich meinen Code veröffentlichen, wobei calculateWeightForPointI den eigentlichen Algorithmus enthält. Und als Referenz: here is the information i'm trying to follow. wäre ich so dankbar, wenn jemand mich suchen könnte.

void updateCurve(const std::vector<glm::vec3>& controls, std::vector<glm::vec3>& samples) 
{ 
    int subCurveOrder = 4; // = k = I want to break my curve into to cubics 

    // De boor 1st attempt 
    if(controls.size() >= subCurveOrder) 
    { 
     createKnotVector(subCurveOrder, controls.size()); 
     samples.clear(); 

     for(int steps=0; steps<=20; steps++) 
     { 
      // use steps to get a 0-1 range value for progression along the curve 
        // then get that value into the range [k-1, n+1] 
      // k-1 = subCurveOrder-1 
      // n+1 = always the number of total control points 

      float t = (steps/20.0f) * (controls.size() - (subCurveOrder-1)) + subCurveOrder-1; 

      glm::vec3 newPoint(0,0,0); 
      for(int i=1; i <= controls.size(); i++) 
      { 
       float weightForControl = calculateWeightForPointI(i, subCurveOrder, controls.size(), t); 
       newPoint += weightForControl * controls.at(i-1); 
      } 
      samples.push_back(newPoint); 
     } 
    } 

} 

    //i = the weight we're looking for, i should go from 1 to n+1, where n+1 is equal to the total number of control points. 
    //k = curve order = power/degree +1. eg, to break whole curve into cubics use a curve order of 4 
    //cps = number of total control points 
    //t = current step/interp value 
float calculateWeightForPointI(int i, int k, int cps, float t) 
    { 
     //test if we've reached the bottom of the recursive call 
     if(k == 1) 
     { 
      if(t >= knot(i) && t < knot(i+1)) 
       return 1; 
      else 
       return 0; 
     } 

     float numeratorA = (t - knot(i)); 
     float denominatorA = (knot(i + k-1) - knot(i)); 
     float numeratorB = (knot(i + k) - t); 
     float denominatorB = (knot(i + k) - knot(i + 1)); 

     float subweightA = 0; 
     float subweightB = 0; 

     if(denominatorA != 0) 
      subweightA = numeratorA/denominatorA * calculateWeightForPointI(i, k-1, cps, t); 
     if(denominatorB != 0) 
      subweightB = numeratorB/denominatorB * calculateWeightForPointI(i+1, k-1, cps, t); 

     return subweightA + subweightB; 

    } 

    //returns the knot value at the passed in index 
    //if i = 1 and we want Xi then we have to remember to index with i-1 
float knot(int indexForKnot) 
    { 
     // When getting the index for the knot function i remember to subtract 1 from i because of the difference caused by us counting from i=1 to n+1 and indexing a vector from 0 
     return knotVector.at(indexForKnot-1); 
    } 
    //calculate the whole knot vector 
void createKnotVector(int curveOrderK, int numControlPoints) 
    { 
     int knotSize = curveOrderK + numControlPoints; 
     for(int count = 0; count < knotSize; count++) 
     { 
      knotVector.push_back(count); 
     } 
    } 
+0

http://chi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c/ Sie – Saqlain

+0

B-Splines wenig Hilfe die konvexe Hülle Eigenschaft aufweisen bekommen . Wenn Sie von jedem nachfolgenden Kontrollpunkt eine Linie zeichnen, erhalten Sie dann ein konvexes Polygon? Es sieht so aus, als ob sich einige Kanten schneiden. –

+0

@BrettHale Ich fürchte, ich folge nicht ganz? Ich arbeite gerade in 2D, aber keiner der Ränder meiner B-Linie (wie durch die weißen Punkte definiert) scheint sich zu schneiden. Oh, warte, reden wir über die Überlappung der Kontrollpunkte? Das ist Absicht, die 5., 6. und 7. Punkte überlappen die 1., 2. und 3. Punkte beim Versuch, einen Kreis zu zeichnen. Danke, dass du dir die Zeit genommen hast, um mir zu helfen, das zu lösen, ich kämpfe wirklich. – Holly

Antwort

2

Ihr Algorithmus scheint für alle Eingaben zu funktionieren, die ich ausprobiert habe. Ihr Problem könnte sein, dass ein Kontrollpunkt nicht dort ist, wo er sein sollte oder dass er nicht richtig initialisiert wurde. Es sieht so aus, als gäbe es zwei Kontrollpunkte, die halbe Höhe unter der linken unteren Ecke.

Correct Wrong

Verwandte Themen