通过matlab中的数据点集从B样条曲线中找到控制点

时间:2016-06-18 23:06:07

标签: matlab graphics reverse-engineering curve bspline

我使用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

我使用向心方法从曲线中找到控制点,如下图所示 enter image description here

完成我的代码:

% 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矩阵

enter image description here 并且要计算B-Spline中的N,我们必须使用这些递归函数 enter image description here

完成我的代码:

% 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为对该曲线应用逆向工程后的结果控制点,因此该值与原始数据点值相比如此之小 enter image description here

更新的(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

1 个答案:

答案 0 :(得分:1)

我认为您的方法存在一些可疑问题:

  • 首先,如果您尝试创建一个b样条曲线,插补103个输入点(并且不会施加其他边界条件),则b样条曲线将具有103个控制点,无论b样条曲线的程度如何。
  • U_K数组是分配给每个输入点的参数。它们与Cox DeBoor递归公式使用的结序列ti不同。如果b样条曲线为3度,则结点序列中应有(103 + 3 + 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)个结。