]> Creatis software - CreaPhase.git/blobdiff - 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
diff --git a/octave_packages/nurbs-1.3.6/nrbmak.m b/octave_packages/nurbs-1.3.6/nrbmak.m
new file mode 100644 (file)
index 0000000..dd10ce0
--- /dev/null
@@ -0,0 +1,245 @@
+function nurbs = nrbmak(coefs,knots)
+%
+% NRBMAK: Construct the NURBS structure given the control points
+%            and the knots.
+% 
+% Calling Sequence:
+% 
+%   nurbs   = nrbmak(cntrl,knots);
+% 
+% INPUT:
+% 
+%   cntrl       : Control points, these can be either Cartesian or
+%              homogeneous coordinates.
+% 
+%              For a curve the control points are represented by a
+%              matrix of size (dim,nu), for a surface a multidimensional
+%              array of size (dim,nu,nv), for a volume a multidimensional array
+%              of size (dim,nu,nv,nw). Where nu is number of points along
+%              the parametric U direction, nv the number of points along
+%              the V direction and nw the number of points along the W direction. 
+%              dim is the dimension. Valid options
+%              are
+%              2 .... (x,y)        2D Cartesian coordinates
+%              3 .... (x,y,z)      3D Cartesian coordinates
+%              4 .... (wx,wy,wz,w) 4D homogeneous coordinates
+% 
+%   knots      : Non-decreasing knot sequence spanning the interval
+%               [0.0,1.0]. It's assumed that the geometric entities
+%               are clamped to the start and end control points by knot
+%               multiplicities equal to the spline order (open knot vector).
+%               For curve knots form a vector and for surfaces (volumes)
+%               the knots are stored by two (three) vectors for U and V (and W)
+%               in a cell structure {uknots vknots} ({uknots vknots wknots}).
+%               
+% OUTPUT:
+% 
+%   nurbs      : Data structure for representing a NURBS entity
+% 
+% NURBS Structure:
+% 
+%   Both curves and surfaces are represented by a structure that is
+%   compatible with the Spline Toolbox from Mathworks
+% 
+%      nurbs.form   .... Type name 'B-NURBS'
+%      nurbs.dim    .... Dimension of the control points
+%      nurbs.number .... Number of Control points
+%       nurbs.coefs  .... Control Points
+%       nurbs.order  .... Order of the spline
+%       nurbs.knots  .... Knot sequence
+% 
+%   Note: the control points are always converted and stored within the
+%   NURBS structure as 4D homogeneous coordinates. A curve is always stored 
+%   along the U direction, and the vknots element is an empty matrix. For
+%   a surface the spline order is a vector [du,dv] containing the order
+%   along the U and V directions respectively. For a volume the order is
+%   a vector [du dv dw]. Recall that order = degree + 1.
+% 
+% Description:
+% 
+%   This function is used as a convenient means of constructing the NURBS
+%   data structure. Many of the other functions in the toolbox rely on the 
+%   NURBS structure been correctly defined as shown above. The nrbmak not
+%   only constructs the proper structure, but also checks for consistency.
+%   The user is still free to build his own structure, in fact a few
+%   functions in the toolbox do this for convenience.
+% 
+% Examples:
+% 
+%   Construct a 2D line from (0.0,0.0) to (1.5,3.0).
+%   For a straight line a spline of order 2 is required.
+%   Note that the knot sequence has a multiplicity of 2 at the
+%   start (0.0,0.0) and end (1.0 1.0) in order to clamp the ends.
+% 
+%   line = nrbmak([0.0 1.5; 0.0 3.0],[0.0 0.0 1.0 1.0]);
+%   nrbplot(line, 2);
+% 
+%   Construct a surface in the x-y plane i.e
+%     
+%     ^  (0.0,1.0) ------------ (1.0,1.0)
+%     |      |                      |
+%     | V    |                      |
+%     |      |      Surface         |
+%     |      |                      |
+%     |      |                      |
+%     |  (0.0,0.0) ------------ (1.0,0.0)
+%     |
+%     |------------------------------------>
+%                                       U 
+%
+%   coefs = cat(3,[0 0; 0 1],[1 1; 0 1]);
+%   knots = {[0 0 1 1]  [0 0 1 1]}
+%   plane = nrbmak(coefs,knots);
+%   nrbplot(plane, [2 2]);
+%
+%    Copyright (C) 2000 Mark Spink, 2010 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 2 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/>.
+
+nurbs.form   = 'B-NURBS';
+nurbs.dim    = 4;
+np = size(coefs);
+dim = np(1);
+if iscell(knots)
+  if size(knots,2) == 3
+   if (numel(np) == 3)
+     np(4) = 1;
+   elseif (numel(np)==2)
+     np(3:4) = 1;
+   end
+  % constructing a volume 
+   nurbs.number = np(2:4);
+   if (dim < 4)
+     nurbs.coefs = repmat([0.0 0.0 0.0 1.0]',[1 np(2:4)]);
+     nurbs.coefs(1:dim,:,:) = coefs;  
+   else
+     nurbs.coefs = coefs;
+   end
+   uorder = size(knots{1},2)-np(2);
+   vorder = size(knots{2},2)-np(3);
+   worder = size(knots{3},2)-np(4);
+   uknots = sort(knots{1});
+   vknots = sort(knots{2});
+   wknots = sort(knots{3});
+   uknots = (uknots-uknots(1))/(uknots(end)-uknots(1));
+   vknots = (vknots-vknots(1))/(vknots(end)-vknots(1));
+   wknots = (wknots-wknots(1))/(wknots(end)-wknots(1));
+   nurbs.knots = {uknots vknots wknots};
+   nurbs.order = [uorder vorder worder];
+
+  elseif size(knots,2) == 2
+   if (numel(np)==2); np(3) = 1; end
+   % constructing a surface 
+   nurbs.number = np(2:3);
+   if (dim < 4)
+     nurbs.coefs = repmat([0.0 0.0 0.0 1.0]',[1 np(2:3)]);
+     nurbs.coefs(1:dim,:,:) = coefs;  
+   else
+     nurbs.coefs = coefs;
+   end
+   uorder = size(knots{1},2)-np(2);
+   vorder = size(knots{2},2)-np(3);
+   uknots = sort(knots{1});
+   vknots = sort(knots{2});
+   uknots = (uknots-uknots(1))/(uknots(end)-uknots(1));
+   vknots = (vknots-vknots(1))/(vknots(end)-vknots(1));
+   nurbs.knots = {uknots vknots};
+   nurbs.order = [uorder vorder];
+   
+  end
+
+else
+
+  % constructing a curve
+  nurbs.number = np(2);
+  if (dim < 4)
+    nurbs.coefs = repmat([0.0 0.0 0.0 1.0]',[1 np(2)]);
+    nurbs.coefs(1:dim,:) = coefs;  
+  else
+    nurbs.coefs = coefs;
+  end
+  nurbs.order = size(knots,2)-np(2);
+  knots = sort(knots);
+  nurbs.knots = (knots-knots(1))/(knots(end)-knots(1));
+
+end
+
+end
+
+%!demo
+%! pnts = [0.5 1.5 4.5 3.0 7.5 6.0 8.5;
+%!         3.0 5.5 5.5 1.5 1.5 4.0 4.5;
+%!         0.0 0.0 0.0 0.0 0.0 0.0 0.0];
+%! crv = nrbmak(pnts,[0 0 0 1/4 1/2 3/4 3/4 1 1 1]);
+%! nrbplot(crv,100)
+%! title('Test curve')
+%! hold off
+
+%!demo
+%! pnts = [0.5 1.5 4.5 3.0 7.5 6.0 8.5;
+%!         3.0 5.5 5.5 1.5 1.5 4.0 4.5;
+%!         0.0 0.0 0.0 0.0 0.0 0.0 0.0];
+%! crv = nrbmak(pnts,[0 0 0 0.1 1/2 3/4 3/4 1 1 1]);
+%! nrbplot(crv,100)
+%! title('Test curve with a slight variation of the knot vector')
+%! hold off
+
+%!demo
+%! pnts = zeros(3,5,5);
+%! pnts(:,:,1) = [ 0.0  3.0  5.0  8.0 10.0; 
+%!                 0.0  0.0  0.0  0.0  0.0; 
+%!                 2.0  2.0  7.0  7.0  8.0];
+%! pnts(:,:,2) = [ 0.0  3.0  5.0  8.0 10.0;
+%!                 3.0  3.0  3.0  3.0  3.0;
+%!                 0.0  0.0  5.0  5.0  7.0];
+%! pnts(:,:,3) = [ 0.0  3.0  5.0  8.0 10.0;
+%!                 5.0  5.0  5.0  5.0  5.0;
+%!                 0.0  0.0  5.0  5.0  7.0];
+%! pnts(:,:,4) = [ 0.0  3.0  5.0  8.0 10.0;
+%!                 8.0  8.0  8.0  8.0  8.0;
+%!                 5.0  5.0  8.0  8.0 10.0];
+%! pnts(:,:,5) = [ 0.0  3.0  5.0  8.0 10.0;
+%!                10.0 10.0 10.0 10.0 10.0;
+%!                 5.0  5.0  8.0  8.0 10.0];
+%!
+%! knots{1} = [0 0 0 1/3 2/3 1 1 1];
+%! knots{2} = [0 0 0 1/3 2/3 1 1 1];
+%!
+%! srf = nrbmak(pnts,knots);
+%! nrbplot(srf,[20 20])
+%! title('Test surface')
+%! hold off
+
+%!demo
+%! coefs =[ 6.0  0.0  6.0  1;
+%!         -5.5  0.5  5.5  1;
+%!         -5.0  1.0 -5.0  1;
+%!          4.5  1.5 -4.5  1;
+%!          4.0  2.0  4.0  1;
+%!         -3.5  2.5  3.5  1;
+%!         -3.0  3.0 -3.0  1;
+%!          2.5  3.5 -2.5  1;
+%!          2.0  4.0  2.0  1;
+%!         -1.5  4.5  1.5  1;
+%!         -1.0  5.0 -1.0  1;
+%!          0.5  5.5 -0.5  1;
+%!          0.0  6.0  0.0  1]';
+%! knots = [0 0 0 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 1 1 1];
+%!
+%! crv = nrbmak(coefs,knots);
+%! nrbplot(crv,100);
+%! grid on;
+%! title('3D helical curve.');
+%! hold off
+