Mercurial > forge
view extra/nurbs/inst/basiskntins.m @ 12668:7623d14dd29c octave-forge
Change in the help
author | rafavzqz |
---|---|
date | Tue, 28 Jul 2015 10:24:59 +0000 |
parents | e3998369a32e |
children |
line wrap: on
line source
function S = basiskntins (deg,t,u) % Compute the coefficient matrix for non-uniform B-splines subdivision. % % This represents the B-spline basis given by a coarse knot vector % in terms of the B-spline basis of a finer knot vector. % % The function is implemented for the univariate case. It is based on % the paper: % % G. Casciola, L. Romani, A general matrix representation for non-uniform % B-spline subdivision with boundary control, ALMA-DL, University of Bologna (2007) % % Calling Sequence: % % S = basiskntins (deg, t, u); % % INPUT: % % deg - degree of the first knot vector % t - coarse knot vector % u - fine knot vector % % OUTPUT: % % B - Value of the basis functions at the points % size(B)=[numel(u),(p+1)] for curves % or [numel(u)*numel(v), (p+1)*(q+1)] for surfaces % % N - Indices of the basis functions that are nonvanishing at each % point. size(N) == size(B) % % Copyright (C) 2015 Rafael Vazquez % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see <http://www.gnu.org/licenses/>. nt = length(t); nu = length(u); S = sparse (nu-deg-1,nt-deg-1); [t_mult,t_single,nt_s] = knot_mult(deg,t); [u_mult,u_single,nu_s] = knot_mult(deg,u); st = deg+1; su = deg+1; row = 1; col = 1; Sl = bs2bs(deg,t,u,st,su); S(row:deg+row,col:deg+col) = Sl; t_single(nt+1) = t(nt-deg); i = 1; for j=1:nu_s if (u_single(j) == t_single(i)) st = st+t_mult(i); col = col+t_mult(i); i = i+1; end su = su+u_mult(j); row = row+u_mult(j); Sl = bs2bs(deg,t,u,st,su); S(row:deg+row,col:deg+col) = Sl; end end function [t_mult,t_single,nt_s] = knot_mult(d,t) epsilon = 1e-14 * (t(end) - t(1)); nt = length(t); nt_s = 0; m = 1; for i = d+2:nt-d-1 if ((t(i+1) - t(i)) > epsilon) nt_s = nt_s+1; t_mult(nt_s) = m; t_single(nt_s) = t(i); m=1; else m = m+1; end end t_single(nt_s+1)=t(nt-d); t_mult(nt_s+1)=0; end function S = bs2bs(d,t,u,k,l) S = zeros(d+1); S(1,:) = bs2bs_first_row(d,t,u,k,l); for ir=1:d S(ir+1,:) = bs2bs_i_row(d,t,u,k,l,ir,S(ir,:)); end end function S = bs2bs_first_row(d,t,u,k,l) S = eye(1,d+1); for h=1:d beta_2=0.0; uu=u(l+1-h); for j=h:-1:1 d1=uu-t(k+j-h); d2=t(k+j)-uu; beta_1=S(j)/(d2+d1); S(j+1)=d1*beta_1+beta_2; beta_2=d2*beta_1; end S(1)=beta_2; end end function Si = bs2bs_i_row(d,t,u,k,l,ir,S) Si(1) = S(1)*(t(k+1)-u(l+ir))/(t(k+1)-u(l+ir-d)); for j=1:d den=t(k+j+1)-u(l+ir-d); fact=(t(k+j+1)-t(k+j-d))/(t(k+j)-t(k+j-d-1)); Si(j+1)=(fact*(S(j)*(u(l+ir)-t(k+j-d-1))-Si(j) * ... (u(l+ir-d)-t(k+j-d-1)))+S(j+1)*(t(k+j+1)-u(l+ir)))/den; end end %!test %! knt1 = [0 0 0 1/2 1 1 1]; %! knt2 = [0 0 0 1/4 1/2 3/4 1 1 1]; %! C = basiskntins (2, knt1, knt2); %! assert (full(C), [1 0 0 0; 1/2 1/2 0 0; 0 3/4 1/4 0; 0 1/4 3/4 0; 0 0 1/2 1/2; 0 0 0 1]); %!test %! crv = nrbtestcrv; %! crv2 = nrbkntins (crv, [0.1, 0.3, 0.4, 0.5, 0.6, 0.8, 0.96 0.98]); %! C = basiskntins (crv.order-1,crv.knots,crv2.knots); %! for ii = 1:4 %! assert (max (abs(C*crv.coefs(ii,:)' - crv2.coefs(ii,:)')) < 1e-14 ) %! end %!test %! crv = nrbtestcrv; %! crv2 = nrbkntins (crv, [0.50000001, 0.5000001, 0.500001, 0.50001, 0.5001]); %! C = basiskntins (crv.order-1,crv.knots,crv2.knots); %! for ii = 1:4 %! assert (max (abs(C*crv.coefs(ii,:)' - crv2.coefs(ii,:)')) < 1e-14 ) %! end %!test %! crv = nrbtestcrv; %! crv2 = nrbkntins (crv, [0.1, 0.3, 0.4, 0.5, 0.6, 0.8, 0.96 0.98]); %! C = basiskntins (crv.order-1,crv.knots,crv2.knots); %! x = linspace (0, 1, 10); %! s = findspan (crv.number-1, crv.order-1, x, crv.knots); %! s2 = findspan (crv2.number-1, crv2.order-1, x, crv2.knots); %! N = basisfun (s, x, crv.order-1, crv.knots); %! N2 = basisfun (s2, x, crv2.order-1, crv2.knots); %! c = numbasisfun (s, x, crv.order-1, crv.knots) + 1; %! c2 = numbasisfun (s2, x, crv2.order-1, crv2.knots) + 1; %! for ii = 1:numel(x) %! assert (abs(N2(ii,:) * C(c2(ii,:),c(ii,:)) - N(ii,:)) < 1e-14) %! end