2

我正在使用具有 200 个数据点的数据集来绘制 B 样条曲线,我想从该曲线中提取 100 个原始控制点,以便在一种算法中使用它来解决一个问题。控制点的结果与B样条曲线的数据点的值相比太小了所以我不知道我在下面的代码中是否出错了我需要帮助知道因为我必须使用这些控件用一种算法完成我的学习的要点

一组数据点的链接: 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矩阵

在此处输入图像描述 为了在 B-Spline 中计算 N,我们必须使用这些递归函数 在此处输入图像描述

完成我的代码:

% 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

结尾

4

1 回答 1

1

我认为您的方法中有一些可疑的问题:

  • 首先,如果您尝试创建一个插值 103 个输入点的 b 样条曲线(并且不施加其他边界条件),那么无论 b 样条曲线的度数如何,b 样条曲线都会有 103 个控制点。
  • 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] 不会在此步骤中使用。您将有 (nD-1) 个内部结。

2) 现在,将 p[0] 添加到节点值 (D+1) 次的前面,并将 p[n-1] 添加到节点值 (D+1) 次的末尾,您就完成了。最后,您总共将有 (N+D+1) 个结。

于 2016-06-19T18:27:32.627 回答