Home > matGeom > geom3d > drawCircle3d.m

drawCircle3d

PURPOSE ^

Draw a 3D circle.

SYNOPSIS ^

function varargout = drawCircle3d(varargin)

DESCRIPTION ^

 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

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019