我使用200个数据点的数据集来绘制B样条曲线,我想从这条曲线中提取100个原始控制点,以便在一个算法中使用它来解决一个问题。控制的结果与B-Spline曲线的数据点的值相比太小了,所以我不知道在下面的代码中是否出错了我需要帮助才能知道因为我必须使用这些控制点在一个算法中完成我的学习
数据点集的链接: https://drive.google.com/open?id=0B_2BUqaJptbqUkRWLWdmbmpQakk
代码:
% read data set
dataset = importdata("path of data set here");
x = dataset(:,1);
y = dataset(:,2);
for i=1:200
controlpoints(i,1) = x(i);
controlpoints(i,2) = y(i);
controlpoints(i,3) = 0;
end
% Create Q with some points from originla matrix controlpoints ( I take only 103 points)
counter =1;
for i=1:200
if (i==11) || (i==20) || (i==198)
Q(counter,:) = F(i,:);
counter = counter +1;
end
if ne(mod(i,2),0)
Q(counter,:) = F(i,:);
counter = counter+1;
end
end
完成我的代码:
% 2- Create Centripetal Nodes array from Q
CP(1) = 0;
CP(103) =1;
for i=2:102
sum = 0;
for j=2:102
sum = sum + sqrt(sqrt((Q(j,1)-Q(j-1,1))^2+(Q(j,2)-Q(j-1,2))^2));
end
CP(i) = CP(i-1) + (sqrt(sqrt((Q(i,1)-Q(i-1,1))^2+(Q(i,2)-Q(i-1,2))^2))/sum);
end
p=3; % degree
% 3- Create U_K array from CP array
for i=1:103
U_K(i) = CP(i);
end
为了计算控制点,我们必须遵循这个等式P = Qx(R') - > R'是R矩阵的逆,所以我们必须通过上面的方程找到R矩阵然后鳍P(控制点矩阵)。以下场景用于查找R矩阵
完成我的代码:
% 5- Calculate R_i_p matrix
for a=1:100
for b=1:100
R_i_p(a,b) = NCalculate(b,p,U_K(a),U_K);
end
end
% 6- Find inverse of R_i_p matrix
R_i_p_invers = inv(R_i_p);
% 7- Find Control points ( 100 points because we have curve with 3 degree )
for i=1:100
for k=1:100
PX(i) = R_inv(i,k) * Q(k,1);
PY(i) = R_inv(i,k) * Q(k,2);
end
end
PX2 = transpose(PX);
PY2 = transpose(PY);
P = horzcat(PX2,PY2); % The final control points you can see the values is very small compared with the original data points vlaues
我的递归函数找到前面的R矩阵:
function z = NCalculate(j,k,u,U)
if (k == 1 )
if ( (u > U(j)) && (u <= U(j+1)) )
z = 1;
else
z = 0;
end
else
z = (u-U(j)/U(j+k-1)-U(j)* NCalculate(j,k-1,u,U) ) + (U(j+k)-u/U(j+k)-U(j+1) * NCalculate(j+1,k-1,u,U));
end
end
我真的需要这么多的帮助,我在一周内尝试了这个问题:(
更新 图1为主要B样条曲线,图2为对该曲线应用逆向工程后的结果控制点,因此该值与原始数据点值相比如此之小
更新的(2): 我对我的代码做了一些更新,但现在问题出现在R矩阵的逆矩阵中,它给我无限的价值
% 2- Create Centripetal Nodes array from Q
CP(1) = 0;
CP(100) =1;
sum = 0;
for i=2:100
sum = sum + sqrt(sqrt((Q(i,1)-Q(i-1,1))^2+(Q(i,2)-Q(i-1,2))^2));
end
for i=2:99
CP(i) = CP(i-1) + (sqrt(sqrt((Q(i,1)-Q(i-1,1))^2+(Q(i,2)-Q(i-1,2))^2))/sum);
end
% 3- Create U_K array from CP array
for i=1:100
U_K(i) = CP(i);
end
p=3;
% create Knot vector
% The first elements
for i=1:p+1
U(i) = 0;
end
% The last elements
for i=100:99+p+1
U(i) = 1;
end
% The remain elements
for j=2:96
sum = 0;
for i=j:(j+p-1)
sum = sum + U_K(i);
end
U(j+p) = (1/p)* sum;
end
% 5- Calculate R_i_p matrix
for a=1:100
for b=1:100
R_i_p(a,b) = NCalculate(b,p,U_K(a),U);
end
end
R_i_p_invers = inv(R_i_p);
% 7- Find Control points ( 100 points )
for i=1:100
for k=1:100
if isinf(R_inv(i,k))
R_inv(i,k) = 0;
end
PX(i) = R_inv(i,k) * Q(k,1);
PY(i) = R_inv(i,k) * Q(k,2);
end
end
PX2 = transpose(PX);
PY2 = transpose(PY);
P = horzcat(PX2,PY2);
注意:我更新了我的NCalculate递归函数,如果结果是NaN(不是数字),则给我0
function z = NCalculate(j,k,u,U)
if (k == 1 )
if ( (u >= U(j)) && (u < U(j+1)) )
z = 1;
else
z = 0;
end
else
z = (u-U(j)/U(j+k-1)-U(j)* NCalculate(j,k-1,u,U) ) + (U(j+k)-u/U(j+k)-U(j+1) * NCalculate(j+1,k-1,u,U));
end
if isnan(z)
z =0;
end
端
答案 0 :(得分:1)
我认为您的方法存在一些可疑问题:
0)将参数表示为p [i],其中i = 0到(n-1),p [0] = 0.0,n是点数。
1)将结值创建为
knot[0] = (p[1]+p[2]+p[3])/D (where D is degree)
knot[1] = (p[2]+p[3]+p[4])/D
knot[2] = (p[3]+p[4]+p[5])/D
......
这些是内部结值。您应该注意到此步骤中不会使用p [0]和p [n-1]。你将有(n-D-1)内部结。
2)现在,将p [0]添加到结点值(D + 1)的前面,并将p [n-1]添加到结点值(D + 1)的末尾,然后就完成了。最后,你将得到(N + D + 1)个结。