2013-04-11 5 views
9

몇 주 동안이 작업을 해왔지만 알고리즘이 제대로 작동하지 못하고 끝내 왔습니다. 여기에 내가 달성 한 무엇의 그림입니다 : 모든 것이 작동 된 경우De-Boors 알고리즘을 구현하여 B- 스플라인에 점을 찾는 알고리즘

enter image description here

내가 마지막에 완벽한 원/타원을 기대.

새 컨트롤 포인트 (노란색)를 추가 할 때마다 내 샘플 포인트 (흰색)가 다시 계산됩니다. 4 개의 컨트롤 포인트에서 모든 것이 완벽하게 보입니다. 다시 말하지만, 제 1의 것의 위에 5 번째를 추가해도 괜찮습니다. 그러나 6 번째로는 너무 멀어지기 시작합니다. 그리고 7 위에서 그것은 원점까지 올라갑니다!

아래 코드는 calculateWeightForPointI에 실제 알고리즘이 들어 있습니다. 그리고 참고 - here is the information i'm trying to follow. 누군가가 나를 위해 나를 데려 갈 수 있으면 나는 아주 멋질 것입니다.

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/ 당신이 약간의 도움이 – Saqlain

+0

B 스플라인이 볼록 선체 속성을 전시 얻을 수 있습니다 . 연속 된 각 제어점에서 선을 그리면 볼록한 다각형으로 끝나나요? 일부 가장자리가 교차하는 것처럼 보입니다. –

+0

@BrettHale 나는 아주 따라 다니지 않을 까봐 걱정 되니? 저는 2D로 작업하고 있습니다 만, B- 슬린 곡선 (흰 점으로 정의 됨)의 가장자리 중 어느 것도 교차하지 않는 것 같습니다. 오, 기다려서 컨트롤 포인트가 겹치는 것입니까? 그건 의도적인데, 원을 그리려고 할 때, 1, 2, 3 번 겹쳐서 5, 6, 7 번 째 점들. 이 문제를 해결할 수있는 시간을내어 주셔서 감사합니다. 정말 고심하고 있습니다. – Holly

답변

2

알고리즘은 입력 해 보았습니다. 문제는 제어 지점이 예상되는 위치가 아니거나 제대로 초기화되지 않았기 때문일 수 있습니다. 왼쪽 하단 구석의 절반 높이에 두 개의 조절 점이있는 것처럼 보입니다.

Correct Wrong