B-Spline, letzter Funktionswert immer Null.
Micha
- programmiertechnik
0 Micha
Hallo,
ich habe den Beitrag von Daniel Thoma gelesen und aus interesse mal ein wenig probiert. Als weitere Quelle habe ich noch diese gefunden und benutzt, wobei der Inhalt ähnlich ist.
Zu meinem Problem. Ich erzeuge den Knotenvektor wie bei der Osnabruecker Seite angegeben - wobei das keine Rolle spielt. Mein Problem ist, wenn der Funktionswert im letzten Intervall liegt und mit der Intervallgrenze zusammenfällt; in diesem Fall bekomme ich wohl ein "Null-Polynom" zurück, sodass die Kurve nicht durch den letzten Punkt geht, sondern durch den Ursprung (siehe Screenshot). Der letzte interpolierte Punkt (im Code unten das Array bSplinePoints) ist also 0,0.
Ist das korrekt, sodass die Kurve einfach zum letzten Wert interpoliert wird oder mach ich einen Fehler bzw. ist für den letzten Abschnitt eine Zusatzbedingung einzuführen? Ich hätte erwartet, da die Kurve auch im ersten Punkt beginnt, dass sie auch durch den letzten geht.
Der vollständigkeithalber noch mein Code (MatLab), da mglw. nur ein Laufindex falsch ist.
B-Spline Polynom
[code=Matlab]
function N = BSplinePolynom(i,p,T,t)
if (p==1)
if (T(i)<=t && t<T(i+1))
N=1;
return;
else
N=0;
return;
end
end
N = 0;
if (T(i+p-1) - T(i) ~= 0)
N = (t-T(i)) / (T(i+p-1) - T(i)) * BSplinePolynom(i,p-1,T,t);
end
if (T(i+p) - T(i+1) ~= 0)
N = N + (T(i+p)-t) / (T(i+p) - T(i+1)) * BSplinePolynom(i+1,p-1,T,t);
end
return;
end
[/code]
Berechnung der Stützstellen
[code=Matlab]
function [bSplinePoints T] = BSpline(Points, k, T, interp)
n = size(Points,1)-1;
% Bestimmt Knotenvektor, wenn keiner vorhanden
if (nargin < 3 || isempty(T))
T = zeros(n+k,1);
for j=0:n+k
if (j<k)
T(j+1) = 0;
elseif (k<= j && j <=n)
T(j+1) = j-k+1;
elseif (j>n)
T(j+1) = n-k+2;
end
end
end
if (nargin < 4)
interp = 25;
end
t = 0:1/interp:max(T);
bSplinePoints = zeros(length(t),2);
for j=1:length(t)
for i=1:n+1
bSplinePoints(j,1) = bSplinePoints(j,1) + Points(i,1) * BSplinePolynom(i,k,T,t(j));
bSplinePoints(j,2) = bSplinePoints(j,2) + Points(i,2) * BSplinePolynom(i,k,T,t(j));
end
end
return;
end
[/code]
Und das geplottete Beispiel:
[code=Matlab]
P = [
1 10
6 5
10 7
14 5
19 10
];
k = 3;
bSplinePoints = BSpline(P, k);
[/code]
Vielen Dank für Eure Hilfe!
Mit freundlichem Gruß
Micha
Hallo,
ich denke, ich konnte das Problem lösen. Die Bestimmung der Polynome erfolgt ja immer im Intervall [a,b[. Die zweite Schranke ist daher nicht im Intervall selbst enthalten und wird beim nächsten Polynom mit erfasst [b,c[. Im letzten Intervall fehlt folglich der letzte Grenzwert, der, da es kein weiteres Polynom gibt, nicht berücksichtigt wird. Ich habe daher die Funktion BSplinePolynom modifiziert, dass diese nun prüft, ob es sich um die letzte Intervallsschranke handelt. Der Code sieht wie folgt aus:
[code=Matlab]
function N = BSplinePolynom(i,p,T,t,p0)
if (nargin==4)
p0 = p;
end
if (p==1)
if (T(i)<=t && t<T(i+1)) || (t==T(i+1) && i+p0 == length(T))
N=1;
return;
else
N=0;
return;
end
end
N = 0;
if (T(i+p-1) - T(i) ~= 0)
N = (t-T(i)) / (T(i+p-1) - T(i)) * BSplinePolynom(i,p-1,T,t,p0);
end
if (T(i+p) - T(i+1) ~= 0)
N = N + (T(i+p)-t) / (T(i+p) - T(i+1)) * BSplinePolynom(i+1,p-1,T,t,p0);
end
return;
end [/code]
Ich hoffe, es passt nun. ;-)
Mit freundlichem Gruß
Micha