Draw a 3D circle. Possible calls for the function: drawCircle3d([XC YC ZC R THETA PHI]) drawCircle3d([XC YC ZC R], [THETA PHI]) where XC, YC, ZY are coordinates of circle center, R is the circle radius, PHI and THETA are 3D angles in degrees of the normal to the plane containing the circle: * THETA between 0 and 180 degrees, corresponding to the colatitude (angle with Oz axis). * PHI between 0 and 360 degrees corresponding to the longitude (angle with Ox axis) drawCircle3d([XC YC ZC R THETA PHI PSI]) drawCircle3d([XC YC ZC R], [THETA PHI PSI]) drawCircle3d([XC YC ZC R], THETA, PHI) drawCircle3d([XC YC ZC], R, THETA, PHI) drawCircle3d([XC YC ZC R], THETA, PHI, PSI) drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) drawCircle3d(XC, YC, ZC, R, THETA, PHI) drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) Are other possible syntaxes for this function. H = drawCircle3d(...) return handle on the created LINE object Example % display 3 mutually orthogonal 3D circles figure; hold on; drawCircle3d([10 20 30 50 0 0], 'LineWidth', 2, 'Color', 'b'); drawCircle3d([10 20 30 50 90 0], 'LineWidth', 2, 'Color', 'r'); drawCircle3d([10 20 30 50 90 90], 'LineWidth', 2, 'Color', 'g'); axis equal; axis([-50 100 -50 100 -50 100]); view([-10 20]) % Draw several circles at once center = [10 20 30]; circ1 = [center 50 0 0]; circ2 = [center 50 90 0]; circ3 = [center 50 90 90]; figure; hold on; drawCircle3d([circ1 ; circ2 ; circ3]); axis equal; See also: circles3d, drawCircleArc3d, drawEllipse3d, drawSphere
0001 function varargout = drawCircle3d(varargin) 0002 % Draw a 3D circle. 0003 % 0004 % Possible calls for the function: 0005 % drawCircle3d([XC YC ZC R THETA PHI]) 0006 % drawCircle3d([XC YC ZC R], [THETA PHI]) 0007 % 0008 % where XC, YC, ZY are coordinates of circle center, R is the circle 0009 % radius, PHI and THETA are 3D angles in degrees of the normal to the 0010 % plane containing the circle: 0011 % * THETA between 0 and 180 degrees, corresponding to the colatitude 0012 % (angle with Oz axis). 0013 % * PHI between 0 and 360 degrees corresponding to the longitude (angle 0014 % with Ox axis) 0015 % 0016 % drawCircle3d([XC YC ZC R THETA PHI PSI]) 0017 % drawCircle3d([XC YC ZC R], [THETA PHI PSI]) 0018 % drawCircle3d([XC YC ZC R], THETA, PHI) 0019 % drawCircle3d([XC YC ZC], R, THETA, PHI) 0020 % drawCircle3d([XC YC ZC R], THETA, PHI, PSI) 0021 % drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) 0022 % drawCircle3d(XC, YC, ZC, R, THETA, PHI) 0023 % drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) 0024 % Are other possible syntaxes for this function. 0025 % 0026 % H = drawCircle3d(...) 0027 % return handle on the created LINE object 0028 % 0029 % Example 0030 % % display 3 mutually orthogonal 3D circles 0031 % figure; hold on; 0032 % drawCircle3d([10 20 30 50 0 0], 'LineWidth', 2, 'Color', 'b'); 0033 % drawCircle3d([10 20 30 50 90 0], 'LineWidth', 2, 'Color', 'r'); 0034 % drawCircle3d([10 20 30 50 90 90], 'LineWidth', 2, 'Color', 'g'); 0035 % axis equal; 0036 % axis([-50 100 -50 100 -50 100]); 0037 % view([-10 20]) 0038 % 0039 % % Draw several circles at once 0040 % center = [10 20 30]; 0041 % circ1 = [center 50 0 0]; 0042 % circ2 = [center 50 90 0]; 0043 % circ3 = [center 50 90 90]; 0044 % figure; hold on; 0045 % drawCircle3d([circ1 ; circ2 ; circ3]); 0046 % axis equal; 0047 % 0048 % See also: 0049 % circles3d, drawCircleArc3d, drawEllipse3d, drawSphere 0050 0051 % 0052 % ------ 0053 % Author: David Legland 0054 % e-mail: david.legland@inra.fr 0055 % Created: 2005-02-17 0056 % Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). 0057 0058 % HISTORY 0059 % 14/12/2006 allows unspecified PHI and THETA 0060 % 04/01/2007 update doc, add todo for angle convention 0061 % 19/06/2009 use localToGlobal3d, add drawing options 0062 % 08/03/2010 use drawPolyline3d 0063 % 2011-06-20 use angles in degrees, support several circles, update doc 0064 0065 0066 % Possible calls for the function, with number of arguments : 0067 % drawCircle3d([XC YC ZC R THETA PHI]) 1 0068 % drawCircle3d([XC YC ZC R THETA PHI PSI]) 1 0069 % drawCircle3d([XC YC ZC R], [THETA PHI]) 2 0070 % drawCircle3d([XC YC ZC R], [THETA PHI PSI]) 2 0071 % drawCircle3d([XC YC ZC R], THETA, PHI) 3 0072 % drawCircle3d([XC YC ZC], R, THETA, PHI) 4 0073 % drawCircle3d([XC YC ZC R], THETA, PHI, PSI) 4 0074 % drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) 5 0075 % drawCircle3d(XC, YC, ZC, R, THETA, PHI) 6 0076 % drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) 7 0077 0078 % parse axis handle 0079 hAx = gca; 0080 if isAxisHandle(varargin{1}) 0081 hAx = varargin{1}; 0082 varargin(1) = []; 0083 end 0084 0085 % extract drawing options 0086 if verLessThan('matlab', '7.8') 0087 ind = find(cellfun('isclass', varargin, 'char'), 1, 'first'); 0088 else 0089 ind = find(cellfun(@ischar, varargin), 1, 'first'); 0090 end 0091 options = {}; 0092 if ~isempty(ind) 0093 options = varargin(ind:end); 0094 varargin(ind:end) = []; 0095 end 0096 0097 % Extract circle data 0098 if length(varargin) == 1 0099 % get center and radius 0100 circle = varargin{1}; 0101 xc = circle(:,1); 0102 yc = circle(:,2); 0103 zc = circle(:,3); 0104 r = circle(:,4); 0105 0106 % get colatitude of normal 0107 if size(circle, 2) >= 5 0108 theta = circle(:,5); 0109 else 0110 theta = zeros(size(circle, 1), 1); 0111 end 0112 0113 % get azimut of normal 0114 if size(circle, 2)>=6 0115 phi = circle(:,6); 0116 else 0117 phi = zeros(size(circle, 1), 1); 0118 end 0119 0120 % get roll 0121 if size(circle, 2)==7 0122 psi = circle(:,7); 0123 else 0124 psi = zeros(size(circle, 1), 1); 0125 end 0126 0127 elseif length(varargin) == 2 0128 % get center and radius 0129 circle = varargin{1}; 0130 xc = circle(:,1); 0131 yc = circle(:,2); 0132 zc = circle(:,3); 0133 r = circle(:,4); 0134 0135 % get angle of normal 0136 angle = varargin{2}; 0137 theta = angle(:,1); 0138 phi = angle(:,2); 0139 0140 % get roll 0141 if size(angle, 2)==3 0142 psi = angle(:,3); 0143 else 0144 psi = zeros(size(angle, 1), 1); 0145 end 0146 0147 elseif length(varargin) == 3 0148 % get center and radius 0149 circle = varargin{1}; 0150 xc = circle(:,1); 0151 yc = circle(:,2); 0152 zc = circle(:,3); 0153 r = circle(:,4); 0154 0155 % get angle of normal and roll 0156 theta = varargin{2}; 0157 phi = varargin{3}; 0158 psi = zeros(size(phi, 1), 1); 0159 0160 elseif length(varargin) == 4 0161 % get center and radius 0162 circle = varargin{1}; 0163 xc = circle(:,1); 0164 yc = circle(:,2); 0165 zc = circle(:,3); 0166 0167 if size(circle, 2)==4 0168 r = circle(:,4); 0169 theta = varargin{2}; 0170 phi = varargin{3}; 0171 psi = varargin{4}; 0172 else 0173 r = varargin{2}; 0174 theta = varargin{3}; 0175 phi = varargin{4}; 0176 psi = zeros(size(phi, 1), 1); 0177 end 0178 0179 elseif length(varargin) == 5 0180 % get center and radius 0181 circle = varargin{1}; 0182 xc = circle(:,1); 0183 yc = circle(:,2); 0184 zc = circle(:,3); 0185 r = varargin{2}; 0186 theta = varargin{3}; 0187 phi = varargin{4}; 0188 psi = varargin{5}; 0189 0190 elseif length(varargin) == 6 0191 xc = varargin{1}; 0192 yc = varargin{2}; 0193 zc = varargin{3}; 0194 r = varargin{4}; 0195 theta = varargin{5}; 0196 phi = varargin{6}; 0197 psi = zeros(size(phi, 1), 1); 0198 0199 elseif length(varargin) == 7 0200 xc = varargin{1}; 0201 yc = varargin{2}; 0202 zc = varargin{3}; 0203 r = varargin{4}; 0204 theta = varargin{5}; 0205 phi = varargin{6}; 0206 psi = varargin{7}; 0207 0208 else 0209 error('drawCircle3d: please specify center and radius'); 0210 end 0211 0212 % circle parametrisation (by using N=60, some vertices are located at 0213 % special angles like 45°, 30°...) 0214 Nt = 60; 0215 t = linspace(0, 2*pi, Nt+1); 0216 0217 nCircles = length(xc); 0218 h = zeros(nCircles, 1); 0219 0220 for i = 1:nCircles 0221 % compute position of circle points 0222 x = r(i) * cos(t)'; 0223 y = r(i) * sin(t)'; 0224 z = zeros(length(t), 1); 0225 circle0 = [x y z]; 0226 0227 % compute transformation from local basis to world basis 0228 trans = localToGlobal3d(xc(i), yc(i), zc(i), theta(i), phi(i), psi(i)); 0229 0230 % compute points of transformed circle 0231 circle = transformPoint3d(circle0, trans); 0232 0233 % draw the curve of circle points 0234 h(i) = drawPolyline3d(hAx, circle, options{:}); 0235 end 0236 0237 0238 if nargout > 0 0239 varargout = {h}; 0240 end