]> Creatis software - CreaPhase.git/blob - octave_packages/nurbs-1.3.6/tbasisfun.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / nurbs-1.3.6 / tbasisfun.m
1 function [N, Nder] = tbasisfun (u, p, U)
2 %
3 % TBASISFUN: Compute a B- or T-Spline basis function, and its derivatives, from its local knot vector.
4 %
5 % usage:
6 %
7 % [N, Nder] = tbasisfun (u, p, U)
8 % [N, Nder] = tbasisfun ([u; v], [p q], {U, V})
9 % [N, Nder] = tbasisfun ([u; v; w], [p q r], {U, V, W})
10
11 % INPUT:
12 %
13 %  u or [u; v] : points in parameter space where the basis function is to be
14 %  evaluated 
15 %  
16 %  U or {U, V} : local knot vector
17 %
18 % p or [p q] : polynomial order of the basis function
19 %
20 % OUTPUT:
21 %
22 %  N    : basis function evaluated at the given parametric points 
23 %  Nder : basis function gradient evaluated at the given parametric points 
24 %
25 %    Copyright (C) 2009 Carlo de Falco
26 %    Copyright (C) 2012 Rafael Vazquez
27 %
28 %    This program is free software: you can redistribute it and/or modify
29 %    it under the terms of the GNU General Public License as published by
30 %    the Free Software Foundation, either version 2 of the License, or
31 %    (at your option) any later version.
32
33 %    This program is distributed in the hope that it will be useful,
34 %    but WITHOUT ANY WARRANTY; without even the implied warranty of
35 %    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36 %    GNU General Public License for more details.
37 %
38 %    You should have received a copy of the GNU General Public License
39 %    along with this program.  If not, see <http://www.gnu.org/licenses/>.
40   
41   if (~ iscell (U))
42     U = sort (U);
43     if (numel (U) ~= p+2)
44       error ('tbasisfun: knot vector and degree do not correspond')
45     end
46     
47     if (nargout == 1)
48       N = onebasisfun__ (u, p, U);
49     else
50       [N, Nder] = onebasisfunder__ (u, p, U);
51     end
52     
53   elseif (size(U,2) == 2)
54     U{1} = sort(U{1}); U{2} = sort(U{2});
55     if (numel(U{1}) ~= p(1)+2 || numel(U{2}) ~= p(2)+2)
56       error ('tbasisfun: knot vector and degree do not correspond')
57     end
58     
59     if (nargout == 1)
60       Nu = onebasisfun__ (u(1,:), p(1), U{1});
61       Nv = onebasisfun__ (u(2,:), p(2), U{2});
62
63       N = Nu.*Nv;
64     elseif (nargout == 2)
65       [Nu, Ndu] = onebasisfunder__ (u(1,:), p(1), U{1});
66       [Nv, Ndv] = onebasisfunder__ (u(2,:), p(2), U{2});
67
68       N = Nu.*Nv;
69       Nder(1,:) = Ndu.*Nv;
70       Nder(2,:) = Nu.*Ndv;
71     end
72     
73   elseif (size(U,2) == 3)
74     U{1} = sort(U{1}); U{2} = sort(U{2}); U{3} = sort(U{3});
75     if (numel(U{1}) ~= p(1)+2 || numel(U{2}) ~= p(2)+2 || numel(U{3}) ~= p(3)+2)
76       error ('tbasisfun: knot vector and degree do not correspond')
77     end
78
79     if (nargout == 1)
80       Nu = onebasisfun__ (u(1,:), p(1), U{1});
81       Nv = onebasisfun__ (u(2,:), p(2), U{2});
82       Nw = onebasisfun__ (u(3,:), p(3), U{3});
83
84       N = Nu.*Nv.*Nw;
85     else
86       [Nu, Ndu] = onebasisfunder__ (u(1,:), p(1), U{1});
87       [Nv, Ndv] = onebasisfunder__ (u(2,:), p(2), U{2});
88       [Nw, Ndw] = onebasisfunder__ (u(3,:), p(3), U{3});
89       
90       N = Nu.*Nv.*Nw;
91       Nder(1,:) = Ndu.*Nv.*Nw;
92       Nder(2,:) = Nu.*Ndv.*Nw;
93       Nder(3,:) = Nu.*Nv.*Ndw;
94     end
95   end
96
97 end
98
99 %!demo
100 %! U = {[0 0 1/2 1 1], [0 0 0 1 1]};
101 %! p = [3, 3];
102 %! [X, Y] = meshgrid (linspace(0, 1, 30));
103 %! u = [X(:), Y(:)]';
104 %! N = tbasisfun (u, p, U);
105 %! surf (X, Y, reshape (N, size(X)))
106 %! title('Basis function associated to a local knot vector')
107 %! hold off
108
109 %!test
110 %! U = [0 1/2 1];
111 %! p = 1;
112 %! u = [0.3 0.4 0.6 0.7];
113 %! [N, Nder] = tbasisfun (u, p, U);
114 %! assert (N, [0.6 0.8 0.8 0.6], 1e-12);
115 %! assert (Nder, [2 2 -2 -2], 1e-12);
116
117 %!test
118 %! U = {[0 1/2 1] [0 1/2 1]};
119 %! p = [1 1];
120 %! u = [0.3 0.4 0.6 0.7; 0.3 0.4 0.6 0.7];
121 %! [N, Nder] = tbasisfun (u, p, U);
122 %! assert (N, [0.36 0.64 0.64 0.36], 1e-12);
123 %! assert (Nder, [1.2 1.6 -1.6 -1.2; 1.2 1.6 -1.6 -1.2], 1e-12);
124
125 %!test
126 %! U = {[0 1/2 1] [0 1/2 1] [0 1/2 1]};
127 %! p = [1 1 1];
128 %! u = [0.4 0.4 0.6 0.6; 0.4 0.4 0.6 0.6; 0.4 0.6 0.4 0.6];
129 %! [N, Nder] = tbasisfun (u, p, U);
130 %! assert (N, [0.512 0.512 0.512 0.512], 1e-12);
131 %! assert (Nder, [1.28 1.28 -1.28 -1.28; 1.28 1.28 -1.28 -1.28; 1.28 -1.28 1.28 -1.28], 1e-12);