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