]> Creatis software - CreaPhase.git/blob - octave_packages/nurbs-1.3.6/nrbmak.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / nurbs-1.3.6 / nrbmak.m
1 function nurbs = nrbmak(coefs,knots)
2 %
3 % NRBMAK: Construct the NURBS structure given the control points
4 %            and the knots.
5
6 % Calling Sequence:
7
8 %   nurbs   = nrbmak(cntrl,knots);
9
10 % INPUT:
11
12 %   cntrl       : Control points, these can be either Cartesian or
13 %               homogeneous coordinates.
14
15 %               For a curve the control points are represented by a
16 %               matrix of size (dim,nu), for a surface a multidimensional
17 %               array of size (dim,nu,nv), for a volume a multidimensional array
18 %               of size (dim,nu,nv,nw). Where nu is number of points along
19 %               the parametric U direction, nv the number of points along
20 %               the V direction and nw the number of points along the W direction. 
21 %               dim is the dimension. Valid options
22 %               are
23 %               2 .... (x,y)        2D Cartesian coordinates
24 %               3 .... (x,y,z)      3D Cartesian coordinates
25 %               4 .... (wx,wy,wz,w) 4D homogeneous coordinates
26
27 %   knots       : Non-decreasing knot sequence spanning the interval
28 %               [0.0,1.0]. It's assumed that the geometric entities
29 %               are clamped to the start and end control points by knot
30 %               multiplicities equal to the spline order (open knot vector).
31 %               For curve knots form a vector and for surfaces (volumes)
32 %               the knots are stored by two (three) vectors for U and V (and W)
33 %               in a cell structure {uknots vknots} ({uknots vknots wknots}).
34 %               
35 % OUTPUT:
36
37 %   nurbs       : Data structure for representing a NURBS entity
38
39 % NURBS Structure:
40
41 %   Both curves and surfaces are represented by a structure that is
42 %   compatible with the Spline Toolbox from Mathworks
43
44 %       nurbs.form   .... Type name 'B-NURBS'
45 %       nurbs.dim    .... Dimension of the control points
46 %       nurbs.number .... Number of Control points
47 %       nurbs.coefs  .... Control Points
48 %       nurbs.order  .... Order of the spline
49 %       nurbs.knots  .... Knot sequence
50
51 %   Note: the control points are always converted and stored within the
52 %   NURBS structure as 4D homogeneous coordinates. A curve is always stored 
53 %   along the U direction, and the vknots element is an empty matrix. For
54 %   a surface the spline order is a vector [du,dv] containing the order
55 %   along the U and V directions respectively. For a volume the order is
56 %   a vector [du dv dw]. Recall that order = degree + 1.
57
58 % Description:
59
60 %   This function is used as a convenient means of constructing the NURBS
61 %   data structure. Many of the other functions in the toolbox rely on the 
62 %   NURBS structure been correctly defined as shown above. The nrbmak not
63 %   only constructs the proper structure, but also checks for consistency.
64 %   The user is still free to build his own structure, in fact a few
65 %   functions in the toolbox do this for convenience.
66
67 % Examples:
68
69 %   Construct a 2D line from (0.0,0.0) to (1.5,3.0).
70 %   For a straight line a spline of order 2 is required.
71 %   Note that the knot sequence has a multiplicity of 2 at the
72 %   start (0.0,0.0) and end (1.0 1.0) in order to clamp the ends.
73
74 %   line = nrbmak([0.0 1.5; 0.0 3.0],[0.0 0.0 1.0 1.0]);
75 %   nrbplot(line, 2);
76
77 %   Construct a surface in the x-y plane i.e
78 %     
79 %     ^  (0.0,1.0) ------------ (1.0,1.0)
80 %     |      |                      |
81 %     | V    |                      |
82 %     |      |      Surface         |
83 %     |      |                      |
84 %     |      |                      |
85 %     |  (0.0,0.0) ------------ (1.0,0.0)
86 %     |
87 %     |------------------------------------>
88 %                                       U 
89 %
90 %   coefs = cat(3,[0 0; 0 1],[1 1; 0 1]);
91 %   knots = {[0 0 1 1]  [0 0 1 1]}
92 %   plane = nrbmak(coefs,knots);
93 %   nrbplot(plane, [2 2]);
94 %
95 %    Copyright (C) 2000 Mark Spink, 2010 Rafael Vazquez
96 %
97 %    This program is free software: you can redistribute it and/or modify
98 %    it under the terms of the GNU General Public License as published by
99 %    the Free Software Foundation, either version 2 of the License, or
100 %    (at your option) any later version.
101
102 %    This program is distributed in the hope that it will be useful,
103 %    but WITHOUT ANY WARRANTY; without even the implied warranty of
104 %    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
105 %    GNU General Public License for more details.
106 %
107 %    You should have received a copy of the GNU General Public License
108 %    along with this program.  If not, see <http://www.gnu.org/licenses/>.
109
110 nurbs.form   = 'B-NURBS';
111 nurbs.dim    = 4;
112 np = size(coefs);
113 dim = np(1);
114 if iscell(knots)
115   if size(knots,2) == 3
116    if (numel(np) == 3)
117      np(4) = 1;
118    elseif (numel(np)==2)
119      np(3:4) = 1;
120    end
121   % constructing a volume 
122    nurbs.number = np(2:4);
123    if (dim < 4)
124      nurbs.coefs = repmat([0.0 0.0 0.0 1.0]',[1 np(2:4)]);
125      nurbs.coefs(1:dim,:,:) = coefs;  
126    else
127      nurbs.coefs = coefs;
128    end
129    uorder = size(knots{1},2)-np(2);
130    vorder = size(knots{2},2)-np(3);
131    worder = size(knots{3},2)-np(4);
132    uknots = sort(knots{1});
133    vknots = sort(knots{2});
134    wknots = sort(knots{3});
135    uknots = (uknots-uknots(1))/(uknots(end)-uknots(1));
136    vknots = (vknots-vknots(1))/(vknots(end)-vknots(1));
137    wknots = (wknots-wknots(1))/(wknots(end)-wknots(1));
138    nurbs.knots = {uknots vknots wknots};
139    nurbs.order = [uorder vorder worder];
140
141   elseif size(knots,2) == 2
142    if (numel(np)==2); np(3) = 1; end
143    % constructing a surface 
144    nurbs.number = np(2:3);
145    if (dim < 4)
146      nurbs.coefs = repmat([0.0 0.0 0.0 1.0]',[1 np(2:3)]);
147      nurbs.coefs(1:dim,:,:) = coefs;  
148    else
149      nurbs.coefs = coefs;
150    end
151    uorder = size(knots{1},2)-np(2);
152    vorder = size(knots{2},2)-np(3);
153    uknots = sort(knots{1});
154    vknots = sort(knots{2});
155    uknots = (uknots-uknots(1))/(uknots(end)-uknots(1));
156    vknots = (vknots-vknots(1))/(vknots(end)-vknots(1));
157    nurbs.knots = {uknots vknots};
158    nurbs.order = [uorder vorder];
159    
160   end
161
162 else
163
164   % constructing a curve
165   nurbs.number = np(2);
166   if (dim < 4)
167     nurbs.coefs = repmat([0.0 0.0 0.0 1.0]',[1 np(2)]);
168     nurbs.coefs(1:dim,:) = coefs;  
169   else
170     nurbs.coefs = coefs;
171   end
172   nurbs.order = size(knots,2)-np(2);
173   knots = sort(knots);
174   nurbs.knots = (knots-knots(1))/(knots(end)-knots(1));
175
176 end
177
178 end
179
180 %!demo
181 %! pnts = [0.5 1.5 4.5 3.0 7.5 6.0 8.5;
182 %!         3.0 5.5 5.5 1.5 1.5 4.0 4.5;
183 %!         0.0 0.0 0.0 0.0 0.0 0.0 0.0];
184 %! crv = nrbmak(pnts,[0 0 0 1/4 1/2 3/4 3/4 1 1 1]);
185 %! nrbplot(crv,100)
186 %! title('Test curve')
187 %! hold off
188
189 %!demo
190 %! pnts = [0.5 1.5 4.5 3.0 7.5 6.0 8.5;
191 %!         3.0 5.5 5.5 1.5 1.5 4.0 4.5;
192 %!         0.0 0.0 0.0 0.0 0.0 0.0 0.0];
193 %! crv = nrbmak(pnts,[0 0 0 0.1 1/2 3/4 3/4 1 1 1]);
194 %! nrbplot(crv,100)
195 %! title('Test curve with a slight variation of the knot vector')
196 %! hold off
197
198 %!demo
199 %! pnts = zeros(3,5,5);
200 %! pnts(:,:,1) = [ 0.0  3.0  5.0  8.0 10.0; 
201 %!                 0.0  0.0  0.0  0.0  0.0; 
202 %!                 2.0  2.0  7.0  7.0  8.0];
203 %! pnts(:,:,2) = [ 0.0  3.0  5.0  8.0 10.0;
204 %!                 3.0  3.0  3.0  3.0  3.0;
205 %!                 0.0  0.0  5.0  5.0  7.0];
206 %! pnts(:,:,3) = [ 0.0  3.0  5.0  8.0 10.0;
207 %!                 5.0  5.0  5.0  5.0  5.0;
208 %!                 0.0  0.0  5.0  5.0  7.0];
209 %! pnts(:,:,4) = [ 0.0  3.0  5.0  8.0 10.0;
210 %!                 8.0  8.0  8.0  8.0  8.0;
211 %!                 5.0  5.0  8.0  8.0 10.0];
212 %! pnts(:,:,5) = [ 0.0  3.0  5.0  8.0 10.0;
213 %!                10.0 10.0 10.0 10.0 10.0;
214 %!                 5.0  5.0  8.0  8.0 10.0];
215 %!
216 %! knots{1} = [0 0 0 1/3 2/3 1 1 1];
217 %! knots{2} = [0 0 0 1/3 2/3 1 1 1];
218 %!
219 %! srf = nrbmak(pnts,knots);
220 %! nrbplot(srf,[20 20])
221 %! title('Test surface')
222 %! hold off
223
224 %!demo
225 %! coefs =[ 6.0  0.0  6.0  1;
226 %!         -5.5  0.5  5.5  1;
227 %!         -5.0  1.0 -5.0  1;
228 %!          4.5  1.5 -4.5  1;
229 %!          4.0  2.0  4.0  1;
230 %!         -3.5  2.5  3.5  1;
231 %!         -3.0  3.0 -3.0  1;
232 %!          2.5  3.5 -2.5  1;
233 %!          2.0  4.0  2.0  1;
234 %!         -1.5  4.5  1.5  1;
235 %!         -1.0  5.0 -1.0  1;
236 %!          0.5  5.5 -0.5  1;
237 %!          0.0  6.0  0.0  1]';
238 %! knots = [0 0 0 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 1 1 1];
239 %!
240 %! crv = nrbmak(coefs,knots);
241 %! nrbplot(crv,100);
242 %! grid on;
243 %! title('3D helical curve.');
244 %! hold off
245