DRAWELLIPSE3D Draw a 3D ellipse. Possible calls for the function : drawEllipse3d([XC YC ZC A B THETA PHI]) drawEllipse3d([XC YC ZC A B THETA PHI PSI]) drawEllipse3d([XC YC ZC A B], [THETA PHI]) drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) drawEllipse3d([XC YC ZC A B], THETA, PHI) drawEllipse3d([XC YC ZC], A, B, THETA, PHI) drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) where XC, YC, ZY are coordinate of ellipse center, A and B are the half-lengths of the major and minor axes of the ellipse, PHI and THETA are 3D angle (in degrees) of the normal to the plane containing the ellipse (PHI between 0 and 360 corresponding to longitude, and THETA from 0 to 180, corresponding to angle with vertical). H = drawEllipse3d(...) return handle on the created LINE object Example figure; axis([-10 10 -10 10 -10 10]); hold on; ellXY = [0 0 0 8 5 0 0 0]; drawEllipse3d(ellXY, 'color', [.8 0 0], 'linewidth', 2) ellXZ = [0 0 0 8 2 90 90 90]; drawEllipse3d(ellXZ, 'color', [0 .8 0], 'linewidth', 2) ellYZ = [0 0 0 5 2 90 0 90]; drawEllipse3d(ellYZ, 'color', [0 0 .8], 'linewidth', 2) See also geom3d, angles3d, drawCircle3d, drawEllipsoid
0001 function varargout = drawEllipse3d(varargin) 0002 %DRAWELLIPSE3D Draw a 3D ellipse. 0003 % 0004 % Possible calls for the function : 0005 % drawEllipse3d([XC YC ZC A B THETA PHI]) 0006 % drawEllipse3d([XC YC ZC A B THETA PHI PSI]) 0007 % drawEllipse3d([XC YC ZC A B], [THETA PHI]) 0008 % drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) 0009 % drawEllipse3d([XC YC ZC A B], THETA, PHI) 0010 % drawEllipse3d([XC YC ZC], A, B, THETA, PHI) 0011 % drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) 0012 % drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) 0013 % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) 0014 % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) 0015 % 0016 % where XC, YC, ZY are coordinate of ellipse center, A and B are the 0017 % half-lengths of the major and minor axes of the ellipse, 0018 % PHI and THETA are 3D angle (in degrees) of the normal to the plane 0019 % containing the ellipse (PHI between 0 and 360 corresponding to 0020 % longitude, and THETA from 0 to 180, corresponding to angle with 0021 % vertical). 0022 % 0023 % H = drawEllipse3d(...) 0024 % return handle on the created LINE object 0025 % 0026 % Example 0027 % figure; axis([-10 10 -10 10 -10 10]); hold on; 0028 % ellXY = [0 0 0 8 5 0 0 0]; 0029 % drawEllipse3d(ellXY, 'color', [.8 0 0], 'linewidth', 2) 0030 % ellXZ = [0 0 0 8 2 90 90 90]; 0031 % drawEllipse3d(ellXZ, 'color', [0 .8 0], 'linewidth', 2) 0032 % ellYZ = [0 0 0 5 2 90 0 90]; 0033 % drawEllipse3d(ellYZ, 'color', [0 0 .8], 'linewidth', 2) 0034 % 0035 % See also 0036 % geom3d, angles3d, drawCircle3d, drawEllipsoid 0037 % 0038 0039 % ------ 0040 % Author: David Legland 0041 % E-mail: david.legland@inrae.fr 0042 % Created: 2008-05-07 0043 % Copyright 2008-2024 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) 0044 0045 % Possible calls for the function, with number of arguments : 0046 % drawEllipse3d([XC YC ZC A B THETA PHI]) 1 0047 % drawEllipse3d([XC YC ZC A B THETA PHI PSI]) 1 0048 % drawEllipse3d([XC YC ZC A B], [THETA PHI]) 2 0049 % drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) 2 0050 % drawEllipse3d([XC YC ZC A B], THETA, PHI) 3 0051 % drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) 4 0052 % drawEllipse3d([XC YC ZC], A, B, THETA, PHI) 5 0053 % drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) 6 0054 % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) 7 0055 % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) 8 0056 0057 % extract handle of axis to draw on 0058 [hAx, varargin] = parseAxisHandle(varargin{:}); 0059 0060 % extract drawing options 0061 ind = find(cellfun(@ischar, varargin), 1, 'first'); 0062 options = {}; 0063 if ~isempty(ind) 0064 options = varargin(ind:end); 0065 varargin(ind:end) = []; 0066 end 0067 0068 if isscalar(varargin) 0069 % get center and radius 0070 elli3d = varargin{1}; 0071 xc = elli3d(:,1); 0072 yc = elli3d(:,2); 0073 zc = elli3d(:,3); 0074 a = elli3d(:,4); 0075 b = elli3d(:,5); 0076 0077 % get colatitude of normal 0078 if size(elli3d, 2)>=6 0079 theta = elli3d(:,6); 0080 else 0081 theta = zeros(size(elli3d, 1), 1); 0082 end 0083 0084 % get azimut of normal 0085 if size(elli3d, 2)>=7 0086 phi = elli3d(:,7); 0087 else 0088 phi = zeros(size(elli3d, 1), 1); 0089 end 0090 0091 % get roll 0092 if size(elli3d, 2)==8 0093 psi = elli3d(:,8); 0094 else 0095 psi = zeros(size(elli3d, 1), 1); 0096 end 0097 0098 elseif length(varargin)==2 0099 % get center and radius 0100 elli3d = varargin{1}; 0101 xc = elli3d(:,1); 0102 yc = elli3d(:,2); 0103 zc = elli3d(:,3); 0104 a = elli3d(:,4); 0105 b = elli3d(:,5); 0106 0107 % get angle of normal 0108 angle = varargin{2}; 0109 theta = angle(:,1); 0110 phi = angle(:,2); 0111 0112 % get roll 0113 if size(angle, 2)==3 0114 psi = angle(:,3); 0115 else 0116 psi = zeros(size(angle, 1), 1); 0117 end 0118 0119 elseif length(varargin)==3 0120 % get center and radius 0121 elli3d = varargin{1}; 0122 xc = elli3d(:,1); 0123 yc = elli3d(:,2); 0124 zc = elli3d(:,3); 0125 a = elli3d(:,4); 0126 b = elli3d(:,5); 0127 0128 % get angle of normal and roll 0129 theta = varargin{2}; 0130 phi = varargin{3}; 0131 psi = zeros(size(phi, 1), 1); 0132 0133 elseif length(varargin)==4 0134 % get center and radius 0135 elli3d = varargin{1}; 0136 xc = elli3d(:,1); 0137 yc = elli3d(:,2); 0138 zc = elli3d(:,3); 0139 0140 if size(elli3d, 2)==5 0141 a = elli3d(:,4); 0142 b = elli3d(:,5); 0143 end 0144 0145 theta = varargin{2}; 0146 phi = varargin{3}; 0147 psi = varargin{4}; 0148 0149 elseif length(varargin)==5 0150 % get center and radius 0151 elli3d = varargin{1}; 0152 xc = elli3d(:,1); 0153 yc = elli3d(:,2); 0154 zc = elli3d(:,3); 0155 a = varargin{2}; 0156 b = varargin{3}; 0157 theta = varargin{4}; 0158 phi = varargin{5}; 0159 psi = zeros(size(phi, 1), 1); 0160 0161 elseif length(varargin)==6 0162 elli3d = varargin{1}; 0163 xc = elli3d(:,1); 0164 yc = elli3d(:,2); 0165 zc = elli3d(:,3); 0166 a = varargin{2}; 0167 b = varargin{3}; 0168 theta = varargin{4}; 0169 phi = varargin{5}; 0170 psi = varargin{6}; 0171 0172 elseif length(varargin)==7 0173 xc = varargin{1}; 0174 yc = varargin{2}; 0175 zc = varargin{3}; 0176 a = varargin{4}; 0177 b = varargin{5}; 0178 theta = varargin{6}; 0179 phi = varargin{7}; 0180 psi = zeros(size(phi, 1), 1); 0181 0182 elseif length(varargin)==8 0183 xc = varargin{1}; 0184 yc = varargin{2}; 0185 zc = varargin{3}; 0186 a = varargin{4}; 0187 b = varargin{5}; 0188 theta = varargin{6}; 0189 phi = varargin{7}; 0190 psi = varargin{8}; 0191 0192 else 0193 error('drawEllipse3d: please specify center and radius'); 0194 end 0195 0196 % uses 60 intervals 0197 t = linspace(0, 2*pi, 61)'; 0198 0199 nElli = size(xc, 1); 0200 0201 % save hold state 0202 holdState = ishold(hAx); 0203 hold(hAx, 'on'); 0204 0205 % iterate over ellipses to draw 0206 for i = 1:nElli 0207 % polyline approximation of ellipse, centered and parallel to main axes 0208 xt = a(i) * cos(t); 0209 yt = b(i) * sin(t); 0210 zt = zeros(length(t), 1); 0211 elli2d = [xt yt zt]; 0212 0213 % compute transformation from local basis to world basis 0214 trans = localToGlobal3d(xc(i), yc(i), zc(i), theta(i), phi(i), psi(i)); 0215 0216 % transform points composing the ellipse 0217 elli3d = transformPoint3d(elli2d, trans); 0218 0219 % draw the curve 0220 h = drawPolyline3d(hAx, elli3d, options{:}); 0221 end 0222 0223 % restore hold state 0224 if ~holdState 0225 hold(hAx, 'off'); 0226 end 0227 0228 % format output arguments 0229 if nargout > 0 0230 varargout = {h}; 0231 end 0232