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
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);
}
}
http://chi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c/ Sie – Saqlain
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. –
@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