Home > matGeom > geom3d > drawDome.m

drawDome

PURPOSE ^

DRAWDOME Draw a dome (half-sphere, semi-sphere) as a mesh.

SYNOPSIS ^

function varargout = drawDome(varargin)

DESCRIPTION ^

DRAWDOME Draw a dome (half-sphere, semi-sphere) as a mesh.

   drawDome(DOME)
   Where DOME = [XC YC ZC R], draw the dome centered on the point with
   coordinates [XC YC ZC] and with radius R, using a quad mesh.
 
   drawDome(Dome, V)
   Where DOME = [XC YC ZC R] and V is a vector in the direction of the top
 
   drawDome(CENTER, R, V)
   Where CENTER = [XC YC ZC], specifies the center and the radius with two
   arguments and vector as third argument.
 
   drawDome(XC, YC, ZC, R, V)
   Specifiy dome center, radius and vector as five arguments.

   drawDome(..., NAME, VALUE);
   Specifies one or several options using parameter name-value pairs.
   Available options are usual drawing options, as well as:
   'nPhi'    the number of arcs used for drawing the meridians
   'nTheta'  the number of circles used for drawing the parallels

   H = drawDome(...)
   Return a handle to the graphical object created by the function.

   [X Y Z] = drawDome(...)
   Return the coordinates of the vertices used by the dome. In this
   case, the dome is not drawn.

   Example
   % Draw four domes with different centers
     figure(1); clf; hold on;
     drawDome([0 0 1 1], 'FaceColor', 'b', 'EdgeColor', 'k', 'LineStyle', ':');
     drawDome([0 1 0 1], [0 1 0]);
     drawDome([0 -1 0 0.5], [1 0 0]);
     drawDome([0 -5 4 10], 'FaceAlpha', 0.5, 'EdgeColor', 'r', 'LineStyle', '-');
     view([-30 20]); axis equal; l = light;

   % Draw dome with different settings
     figure(1); clf;
     drawDome([10 20 30 10], [0 0 1], 'linestyle', ':', 'facecolor', 'r');
     axis([0 50 0 50 0 50]); axis equal;
     l = light;

   % The same, but changes style using graphic handle
     figure(1); clf;
     h = drawDome([10 20 30 10], [1 0 0]);
     set(h, 'linestyle', ':');
     set(h, 'facecolor', 'r');
     axis([0 50 0 50 0 50]); axis equal;
     l = light;
   
   % Draw a dome with high resolution
     figure(1); clf;
     h = drawDome([10 20 30 10], 'nPhi', 360, 'nTheta', 180);
     l = light; view(3);


   See also
   drawSphere

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function varargout = drawDome(varargin)
0002 %DRAWDOME Draw a dome (half-sphere, semi-sphere) as a mesh.
0003 %
0004 %   drawDome(DOME)
0005 %   Where DOME = [XC YC ZC R], draw the dome centered on the point with
0006 %   coordinates [XC YC ZC] and with radius R, using a quad mesh.
0007 %
0008 %   drawDome(Dome, V)
0009 %   Where DOME = [XC YC ZC R] and V is a vector in the direction of the top
0010 %
0011 %   drawDome(CENTER, R, V)
0012 %   Where CENTER = [XC YC ZC], specifies the center and the radius with two
0013 %   arguments and vector as third argument.
0014 %
0015 %   drawDome(XC, YC, ZC, R, V)
0016 %   Specifiy dome center, radius and vector as five arguments.
0017 %
0018 %   drawDome(..., NAME, VALUE);
0019 %   Specifies one or several options using parameter name-value pairs.
0020 %   Available options are usual drawing options, as well as:
0021 %   'nPhi'    the number of arcs used for drawing the meridians
0022 %   'nTheta'  the number of circles used for drawing the parallels
0023 %
0024 %   H = drawDome(...)
0025 %   Return a handle to the graphical object created by the function.
0026 %
0027 %   [X Y Z] = drawDome(...)
0028 %   Return the coordinates of the vertices used by the dome. In this
0029 %   case, the dome is not drawn.
0030 %
0031 %   Example
0032 %   % Draw four domes with different centers
0033 %     figure(1); clf; hold on;
0034 %     drawDome([0 0 1 1], 'FaceColor', 'b', 'EdgeColor', 'k', 'LineStyle', ':');
0035 %     drawDome([0 1 0 1], [0 1 0]);
0036 %     drawDome([0 -1 0 0.5], [1 0 0]);
0037 %     drawDome([0 -5 4 10], 'FaceAlpha', 0.5, 'EdgeColor', 'r', 'LineStyle', '-');
0038 %     view([-30 20]); axis equal; l = light;
0039 %
0040 %   % Draw dome with different settings
0041 %     figure(1); clf;
0042 %     drawDome([10 20 30 10], [0 0 1], 'linestyle', ':', 'facecolor', 'r');
0043 %     axis([0 50 0 50 0 50]); axis equal;
0044 %     l = light;
0045 %
0046 %   % The same, but changes style using graphic handle
0047 %     figure(1); clf;
0048 %     h = drawDome([10 20 30 10], [1 0 0]);
0049 %     set(h, 'linestyle', ':');
0050 %     set(h, 'facecolor', 'r');
0051 %     axis([0 50 0 50 0 50]); axis equal;
0052 %     l = light;
0053 %
0054 %   % Draw a dome with high resolution
0055 %     figure(1); clf;
0056 %     h = drawDome([10 20 30 10], 'nPhi', 360, 'nTheta', 180);
0057 %     l = light; view(3);
0058 %
0059 %
0060 %   See also
0061 %   drawSphere
0062 
0063 % ------
0064 % Author: Moritz Schappler
0065 % E-mail: N/A
0066 % Created: 2013-07-27
0067 % Copyright 2013-2024
0068 
0069 % extract handle of axis to draw on
0070 [hAx, varargin] = parseAxisHandle(varargin{:});
0071 
0072 % process input options: when a string is found, assumes this is the
0073 % beginning of options
0074 options = {'FaceColor', 'g', 'LineStyle', 'none'};
0075 for i = 1:length(varargin)
0076     if ischar(varargin{i})
0077         if isscalar(varargin)
0078             options = {'FaceColor', varargin{1}, 'LineStyle', 'none'};
0079         else
0080             options = [options(1:end) varargin(i:end)];
0081         end
0082         varargin = varargin(1:i-1);
0083         break;
0084     end
0085 end
0086 
0087 % Parse the input (try to extract center coordinates and radius)
0088 if isempty(varargin)
0089     % no input: assumes unit dome
0090     xc = 0;    yc = 0; zc = 0;
0091     r = 1;
0092     v = [0;0;1]; 
0093 elseif isscalar(varargin)
0094     % one argument: concatenates center and radius
0095     dome = varargin{1};
0096     xc = dome(:,1);
0097     yc = dome(:,2);
0098     zc = dome(:,3);
0099     r  = dome(:,4);
0100     v = [0;0;1]; 
0101 elseif length(varargin) == 2
0102     % two arguments: concatenates center and radius with Rotation
0103     dome = varargin{1};
0104     xc = dome(:,1);
0105     yc = dome(:,2);
0106     zc = dome(:,3);
0107     r  = dome(:,4);
0108     v = varargin{2}; 
0109 elseif length(varargin) == 3
0110     % three arguments, corresponding to center and radius and rotation
0111     center = varargin{1};
0112     xc = center(1);
0113     yc = center(2);
0114     zc = center(3);
0115     r  = varargin{2};
0116     v  = varargin{3};
0117 elseif length(varargin) == 5
0118     % five arguments, corresponding to XC, YX, ZC, R and V
0119     xc = varargin{1};
0120     yc = varargin{2};
0121     zc = varargin{3};
0122     r  = varargin{4};
0123     v  = varargin{5};
0124 else
0125     error('drawDome: please specify center and radius');
0126 end
0127 
0128 % Rotation given by z-Axis. Calculate rotation matrix
0129 v = v(:) / norm(v(:));
0130 if all(abs(v(:)-[0;0;1]) < 1e-10)
0131     RM = eye(3);
0132 elseif all(abs(v(:) - [0;0;-1]) < 1e-10)
0133     RM = [[1;0;0], [0; -1; 0], [0; 0; -1]];
0134 else
0135     % z-axis given by argument
0136     ez = v(:);
0137     % x-axis perpendicular
0138     ex = cross(ez, [0; 0; 1]); ex = ex/norm(ex);
0139     % y-axis to create right-handed coordinate system
0140     ey = cross(ez, ex);
0141     RM = [ex, ey, ez];
0142 end
0143 
0144 % number of meridians
0145 nPhi = 32;
0146 ind = find(strcmpi('nPhi', options(1:2:end)));
0147 if ~isempty(ind)
0148     ind = ind(1);
0149     nPhi = options{2*ind};
0150     options(2*ind-1:2*ind) = [];
0151 end
0152     
0153 % number of parallels
0154 nTheta  = 8;
0155 ind = find(strcmpi('nTheta', options(1:2:end)));
0156 if ~isempty(ind)
0157     ind = ind(1);
0158     nTheta = options{2*ind};
0159     options(2*ind-1:2*ind) = [];
0160 end
0161 
0162 % compute spherical coordinates
0163 theta   = linspace(0, pi/2, nTheta+1);
0164 phi     = linspace(0, 2*pi, nPhi+1);
0165 
0166 % convert to Cartesian coordinates and rotate
0167 % Rotate the Dome
0168 x = zeros(nPhi+1, nTheta+1);
0169 y = x;
0170 z = x;
0171 
0172 sintheta = sin(theta);
0173 dx = cos(phi')*sintheta*r;
0174 dy = sin(phi')*sintheta*r;
0175 dz = ones(length(phi),1)*cos(theta)*r;
0176 
0177 for i = 1:nPhi+1
0178     for j = 1:nTheta+1
0179         dxyz = RM*[dx(i, j);dy(i, j);dz(i, j)];
0180         x(i, j) = xc + dxyz(1);
0181         y(i, j) = yc + dxyz(2);    
0182         z(i, j) = zc + dxyz(3);   
0183     end
0184 end
0185 
0186 % Process output
0187 if nargout == 0
0188     % no output: draw the dome
0189     surf(hAx, x, y, z, options{:});
0190     
0191 elseif nargout == 1
0192     % one output: compute
0193     varargout{1} = surf(hAx, x, y, z, options{:});
0194     
0195 elseif nargout == 3
0196     varargout{1} = x; 
0197     varargout{2} = y; 
0198     varargout{3} = z; 
0199 end

Generated on Thu 21-Nov-2024 11:30:22 by m2html © 2003-2022