Die Umsetzung De Flegel-Algorithmus zum Auffinden von Punkten auf einer B-spline

Ich habe dies für mehrere Wochen, aber nicht in der Lage gewesen, um mein Algorithmus richtig arbeitet und ich bin mit meinem Latein am Ende. Hier ist eine illustration von dem, was ich erreicht habe:

Die Umsetzung De Flegel-Algorithmus zum Auffinden von Punkten auf einer B-spline

Wenn alles geklappt hat, würde ich erwarten, dass ein perfekter Kreis/oval am Ende.

Meine sample-points (in weiß) werden neu berechnet, jedes mal ein neues control point (in gelb) Hinzugefügt. An 4 Kontrollpunkten sieht alles perfekt aus, wieder, wie ich hinzufügen, eine 5. auf der Oberseite des 1. sehen die Dinge in Ordnung, aber dann auf der 6. es startet, gehen Sie zu der Seite und auf der 7. es springt auf die Herkunft!

Unten poste ich meinen code, wo calculateWeightForPointI enthält den eigentlichen Algorithmus. Und für Referenz- hier ist die Informationen, die ich versuche zu Folgen. ich wäre so dankbar, wenn jemand könnte einen Blick für mich.

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);
        }
    } 
  • chi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c können Sie bekommen wenig Hilfe
  • B-splines weisen die konvexe Hülle Eigenschaft. Wenn Sie zeichnen Sie eine Linie von jeder aufeinanderfolgenden Kontrollpunkte, tun Sie am Ende mit einem konvexen polygon? Es sieht aus wie einige Kanten schneiden.
  • Ich fürchte, ich verstehe nicht ganz Folgen? Ich bin nur in 2D, im moment, aber keiner von den Rändern der B-sline-Kennlinie (definiert durch die weißen Punkte) scheinen sich zu kreuzen.. Oh warte, sprechen wir über die Punkte überlappen? Das ist beabsichtigt, 5., 6. und 7. Punkte überlappen sich die 1., 2. und 3. wenn Sie versuchen, einen Kreis zu zeichnen. Vielen Dank für die Zeit nehmen, mir zu helfen, dieses Problem lösen bin ich echt zu kämpfen.
InformationsquelleAutor Holly | 2013-04-11
Schreibe einen Kommentar