]> Creatis software - CreaPhase.git/blob - octave_packages/nurbs-1.3.6/nrbrevolve.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / nurbs-1.3.6 / nrbrevolve.m
1 function surf = nrbrevolve(curve,pnt,vec,theta)
2
3
4 % NRBREVOLVE: Construct a NURBS surface by revolving a NURBS curve, or
5 %  construct a NURBS volume by revolving a NURBS surface.
6
7 % Calling Sequence:
8
9 %   srf = nrbrevolve(crv,pnt,vec[,ang])
10
11 % INPUT:
12
13 %   crv         : NURBS curve or surface to revolve, see nrbmak.
14
15 %   pnt         : Coordinates of the point used to define the axis
16 %               of rotation.
17
18 %   vec         : Vector defining the direction of the rotation axis.
19
20 %   ang         : Angle to revolve the curve, default 2*pi
21 %
22 % OUTPUT:
23 %
24 %   srf         : constructed surface or volume
25
26 % Description:
27
28 %   Construct a NURBS surface by revolving the profile NURBS curve around
29 %   an axis defined by a point and vector.
30
31 % Examples:
32
33 %   Construct a sphere by rotating a semicircle around a x-axis.
34 %
35 %   crv = nrbcirc(1.0,[0 0 0],0,pi);
36 %   srf = nrbrevolve(crv,[0 0 0],[1 0 0]);
37 %   nrbplot(srf,[20 20]);
38 %
39 % NOTE:
40 %
41 %   The algorithm:
42 %
43 %     1) vectrans the point to the origin (0,0,0)
44 %     2) rotate the vector into alignment with the z-axis
45 %
46 %     for each control point along the curve
47 %
48 %     3) determine the radius and angle of control
49 %        point to the z-axis
50 %     4) construct a circular arc in the x-y plane with 
51 %        this radius and start angle and sweep angle theta 
52 %     5) combine the arc and profile, coefs and weights.
53 %  
54 %     next control point
55 %
56 %     6) rotate and vectrans the surface back into position
57 %        by reversing 1 and 2.
58 %
59 %
60 %    Copyright (C) 2000 Mark Spink
61 %    Copyright (C) 2010 Rafael Vazquez
62 %
63 %    This program is free software: you can redistribute it and/or modify
64 %    it under the terms of the GNU General Public License as published by
65 %    the Free Software Foundation, either version 2 of the License, or
66 %    (at your option) any later version.
67
68 %    This program is distributed in the hope that it will be useful,
69 %    but WITHOUT ANY WARRANTY; without even the implied warranty of
70 %    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
71 %    GNU General Public License for more details.
72 %
73 %    You should have received a copy of the GNU General Public License
74 %    along with this program.  If not, see <http://www.gnu.org/licenses/>.
75
76 if (nargin < 3)
77   error('Not enough arguments to construct revolved surface');
78 end
79
80 if (nargin < 4)
81   theta = 2.0*pi;
82 end
83
84 if (iscell (curve.knots) && numel(curve.knots) == 3)
85   error('The function nrbrevolve is not yet ready to create volumes') 
86 end
87
88 % Translate curve the center point to the origin
89 if isempty(pnt)
90   pnt = zeros(3,1);
91 end
92
93 if length(pnt) ~= 3
94   error('All point and vector coordinates must be 3D');
95 end
96
97 % Translate and rotate the original curve or surface into alignment with the z-axis
98 T  = vectrans(-pnt);
99 angx = vecangle(vec(1),vec(3));
100 RY = vecroty(-angx);
101 vectmp = RY*[vecnorm(vec(:));1.0];
102 angy = vecangle(vectmp(2),vectmp(3));
103 RX = vecrotx(angy);
104 curve = nrbtform(curve,RX*RY*T);
105
106 % Construct an arc 
107 arc = nrbcirc(1.0,[],0.0,theta);
108
109 if (iscell (curve.knots))
110 % Construct the revolved volume
111   coefs = zeros([4 arc.number curve.number]);
112   angle = squeeze (vecangle(curve.coefs(2,:,:),curve.coefs(1,:,:)));
113   radius = squeeze (vecmag(curve.coefs(1:2,:,:)));
114   for i = 1:curve.number(1)  
115     for j = 1:curve.number(2)  
116       coefs(:,:,i,j) = vecrotz(angle(i,j))*vectrans([0.0 0.0 curve.coefs(3,i,j)])*...
117           vecscale([radius(i,j) radius(i,j)])*arc.coefs;
118       coefs(4,:,i,j) = coefs(4,:,i,j)*curve.coefs(4,i,j);
119         end
120   end
121   surf = nrbmak(coefs,{arc.knots, curve.knots{:}});
122 else
123 % Construct the revolved surface
124   coefs = zeros(4, arc.number, curve.number);
125   angle = vecangle(curve.coefs(2,:),curve.coefs(1,:));
126   radius = vecmag(curve.coefs(1:2,:));
127   for i = 1:curve.number  
128     coefs(:,:,i) = vecrotz(angle(i))*vectrans([0.0 0.0 curve.coefs(3,i)])*...
129           vecscale([radius(i) radius(i)])*arc.coefs;
130     coefs(4,:,i) = coefs(4,:,i)*curve.coefs(4,i);
131   end
132   surf = nrbmak(coefs,{arc.knots, curve.knots});
133 end
134
135 % Rotate and vectrans the surface back into position
136 T = vectrans(pnt);
137 RX = vecrotx(-angy);
138 RY = vecroty(angx);
139 surf = nrbtform(surf,T*RY*RX);  
140
141 end
142
143 %!demo
144 %! sphere = nrbrevolve(nrbcirc(1,[],0.0,pi),[0.0 0.0 0.0],[1.0 0.0 0.0]);
145 %! nrbplot(sphere,[40 40],'light','on');
146 %! title('Ball and tori - surface construction by revolution');
147 %! hold on;
148 %! torus = nrbrevolve(nrbcirc(0.2,[0.9 1.0]),[0.0 0.0 0.0],[1.0 0.0 0.0]);
149 %! nrbplot(torus,[40 40],'light','on');
150 %! nrbplot(nrbtform(torus,vectrans([-1.8])),[20 10],'light','on');
151 %! hold off;
152
153 %!demo
154 %! pnts = [3.0 5.5 5.5 1.5 1.5 4.0 4.5;
155 %!         0.0 0.0 0.0 0.0 0.0 0.0 0.0;
156 %!         0.5 1.5 4.5 3.0 7.5 6.0 8.5];
157 %! crv = nrbmak(pnts,[0 0 0 1/4 1/2 3/4 3/4 1 1 1]);
158 %! 
159 %! xx = vecrotz(deg2rad(25))*vecroty(deg2rad(15))*vecrotx(deg2rad(20));
160 %! nrb = nrbtform(crv,vectrans([5 5])*xx);
161 %!
162 %! pnt = [5 5 0]';
163 %! vec = xx*[0 0 1 1]';
164 %! srf = nrbrevolve(nrb,pnt,vec(1:3));
165 %!
166 %! p = nrbeval(srf,{linspace(0.0,1.0,100) linspace(0.0,1.0,100)});
167 %! surfl(squeeze(p(1,:,:)),squeeze(p(2,:,:)),squeeze(p(3,:,:)));
168 %! title('Construct of a 3D surface by revolution of a curve.');
169 %! shading interp;
170 %! colormap(copper);
171 %! axis equal;
172 %! hold off
173
174 %!demo
175 %! crv1 = nrbcirc(1,[0 0],0, pi/2);
176 %! crv2 = nrbcirc(2,[0 0],0, pi/2);
177 %! srf = nrbruled (crv1, crv2);
178 %! srf = nrbtform (srf, [1 0 0 0; 0 1 0 1; 0 0 1 0; 0 0 0 1]);
179 %! vol = nrbrevolve (srf, [0 0 0], [1 0 0], pi/2);
180 %! nrbplot(vol, [30 30 30], 'light', 'on')