1 function surf = nrbrevolve(curve,pnt,vec,theta)
4 % NRBREVOLVE: Construct a NURBS surface by revolving a NURBS curve, or
5 % construct a NURBS volume by revolving a NURBS surface.
9 % srf = nrbrevolve(crv,pnt,vec[,ang])
13 % crv : NURBS curve or surface to revolve, see nrbmak.
15 % pnt : Coordinates of the point used to define the axis
18 % vec : Vector defining the direction of the rotation axis.
20 % ang : Angle to revolve the curve, default 2*pi
24 % srf : constructed surface or volume
28 % Construct a NURBS surface by revolving the profile NURBS curve around
29 % an axis defined by a point and vector.
33 % Construct a sphere by rotating a semicircle around a x-axis.
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]);
43 % 1) vectrans the point to the origin (0,0,0)
44 % 2) rotate the vector into alignment with the z-axis
46 % for each control point along the curve
48 % 3) determine the radius and angle of control
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.
56 % 6) rotate and vectrans the surface back into position
57 % by reversing 1 and 2.
60 % Copyright (C) 2000 Mark Spink
61 % Copyright (C) 2010 Rafael Vazquez
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.
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.
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/>.
77 error('Not enough arguments to construct revolved surface');
84 if (iscell (curve.knots) && numel(curve.knots) == 3)
85 error('The function nrbrevolve is not yet ready to create volumes')
88 % Translate curve the center point to the origin
94 error('All point and vector coordinates must be 3D');
97 % Translate and rotate the original curve or surface into alignment with the z-axis
99 angx = vecangle(vec(1),vec(3));
101 vectmp = RY*[vecnorm(vec(:));1.0];
102 angy = vecangle(vectmp(2),vectmp(3));
104 curve = nrbtform(curve,RX*RY*T);
107 arc = nrbcirc(1.0,[],0.0,theta);
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);
121 surf = nrbmak(coefs,{arc.knots, curve.knots{:}});
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);
132 surf = nrbmak(coefs,{arc.knots, curve.knots});
135 % Rotate and vectrans the surface back into position
139 surf = nrbtform(surf,T*RY*RX);
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');
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');
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]);
159 %! xx = vecrotz(deg2rad(25))*vecroty(deg2rad(15))*vecrotx(deg2rad(20));
160 %! nrb = nrbtform(crv,vectrans([5 5])*xx);
163 %! vec = xx*[0 0 1 1]';
164 %! srf = nrbrevolve(nrb,pnt,vec(1:3));
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.');
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')