EZIMPLOT3 Easy to use 3D implicit plotter. EZIMPLOT3(FUN) plots the function FUN(X,Y,Z) = 0 (vectorized or not) over the default domain: -2*PI < X < 2*PI, -2*PI < Y < 2*PI, -2*PI < Z < 2*PI. FUN can be a string, an anonymous function handle, a .M-file handle, an inline function or a symbolic function (see examples below) EZIMPLOT3(FUN,DOMAIN)plots FUN over the specified DOMAIN instead of the default domain. DOMAIN can be vector [XMIN,XMAX,YMIN,YMAX,ZMIN,ZMAX] or vector [A,B] (to plot over A < X < B, A < Y < B, A < Z < B). EZIMPLOT3(..,N) plots FUN using an N-by-N grid. The default value for N is 60.
0001 function h = ezimplot3(varargin) 0002 % EZIMPLOT3 Easy to use 3D implicit plotter. 0003 % EZIMPLOT3(FUN) plots the function FUN(X,Y,Z) = 0 (vectorized or not) 0004 % over the default domain: 0005 % -2*PI < X < 2*PI, -2*PI < Y < 2*PI, -2*PI < Z < 2*PI. 0006 % FUN can be a string, an anonymous function handle, a .M-file handle, an 0007 % inline function or a symbolic function (see examples below) 0008 % 0009 % EZIMPLOT3(FUN,DOMAIN)plots FUN over the specified DOMAIN instead of the 0010 % default domain. DOMAIN can be vector [XMIN,XMAX,YMIN,YMAX,ZMIN,ZMAX] or 0011 % vector [A,B] (to plot over A < X < B, A < Y < B, A < Z < B). 0012 % 0013 % EZIMPLOT3(..,N) plots FUN using an N-by-N grid. The default value for 0014 % N is 60. 0015 0016 % EZIMPLOT3(..,'color') plots FUN with color 'color'. The default value 0017 % for 'color' is 'red'. 'color' must be a valid Matlab color identifier. 0018 % 0019 % EZIMPLOT3(axes_handle,..) plots into the axes with handle axes_handle 0020 % instead of into current axes (gca). 0021 % 0022 % H = EZIMPLOT3(...) returns the handle to the patch object this function 0023 % creates. 0024 % 0025 % Example: 0026 % Plot x^3+exp(y)-cosh(z)=4, between -5 and 5 for x,y and z 0027 % 0028 % via a string: 0029 % f = 'x^3+exp(y)-cosh(z)-4' 0030 % ezimplot3(f,[-5 5]) 0031 % 0032 % via a anonymous function handle: 0033 % f = @(x,y,z) x^3+exp(y)-cosh(z)-4 0034 % ezimplot3(f,[-5 5]) 0035 % 0036 % via a function .m file: 0037 %------------------------------% 0038 % function out = myfun(x,y,z) 0039 % out = x^3+exp(y)-cosh(z)-4; 0040 %------------------------------% 0041 % ezimplot3(@myfun,[-5 5]) or ezimplot('myfun',[-5 5]) 0042 % 0043 % via a inline function: 0044 % f = inline('x^3+exp(y)-cosh(z)-4') 0045 % ezimplot3(f,[-5 5]) 0046 % 0047 % via a symbolic expression: 0048 % syms x y z 0049 % f = x^3+exp(y)-cosh(z)-4 0050 % ezimplot3(f,[-5 5]) 0051 % 0052 % Note: this function do not use the "ezgraph3" standard, like ezsurf, 0053 % ezmesh, etc, does. Because of this, ezimplot3 only tries to imitate that 0054 % interface. A future work must be to modify "ezgraph3" to include a 0055 % routine for implicit surfaces based on this file 0056 % 0057 % Inspired by works of: Artur Jutan UWO 02-02-98 ajutan@julian.uwo.ca 0058 % Made by: Gustavo Morales UC 04-12-09 gmorales@uc.edu.ve 0059 % 0060 0061 %%% Checking & Parsing input arguments: 0062 if ishandle(varargin{1}) 0063 cax = varargin{1}; % User selected axes handle for graphics 0064 axes(cax); 0065 args{:} = varargin{2:end}; %ensuring args be a cell array 0066 else 0067 args = varargin; 0068 end 0069 [fun domain n color] = argcheck(args{:}); 0070 %%% Generating the volumetric domain data: 0071 xm = linspace(domain(1),domain(2),n); 0072 ym = linspace(domain(3),domain(4),n); 0073 zm = linspace(domain(5),domain(6),n); 0074 [x,y,z] = meshgrid(xm,ym,zm); 0075 %%% Formatting "fun" 0076 [f_handle f_text] = fix_fun(fun); % f_handle is the anonymous f-handle for "fun" 0077 % f_text is "fun" ready to be a title 0078 %%% Evaluating "f_handle" in domain: 0079 % try 0080 fvalues = f_handle(x,y,z); % fvalues: volume data 0081 % catch ME 0082 % error('Ezimplot3:Functions', 'FUN must have no more than 3 arguments'); 0083 % end 0084 %%% Making the 3D graph of the 0-level surface of the 4D function "fun": 0085 h = patch(isosurface(x,y,z,fvalues,0)); % "patch" handles the structure... 0086 % sent by "isosurface" 0087 isonormals(x,y,z,fvalues,h)% Recalculating the isosurface normals based... 0088 % on the volume data 0089 set(h,'FaceColor',color,'EdgeColor','none'); 0090 %%% Aditional graphic details: 0091 xlabel('x');ylabel('y');zlabel('z');% naming the axis 0092 alpha(0.7) % adjusting for some transparency 0093 grid on; view([1,1,1]); axis equal; camlight; lighting gouraud 0094 %%% Showing title: 0095 title([f_text,' = 0']); 0096 % 0097 %--------------------------------------------Sub-functions HERE--- 0098 function [f dom n color] = argcheck(varargin) 0099 %ARGCHECK(arg) parses "args" to the variables "f"(function),"dom"(domain) 0100 %,"n"(grid size) and "c"(color)and TRIES to check its validity 0101 switch nargin 0102 case 0 0103 error('Ezimplot3:Arguments',... 0104 'At least "fun" argument must be given'); 0105 case 1 0106 f = varargin{1}; 0107 dom = [-2*pi, 2*pi]; % default domain: -2*pi < xi < 2*pi 0108 n = 60; % default grid size 0109 color = 'red'; % default graph color 0110 case 2 0111 f = varargin{1}; 0112 if isa(varargin{2},'double') && length(varargin{2})>1 0113 dom = varargin{2}; 0114 n = 60; 0115 color = 'red'; 0116 elseif isa(varargin{2},'double') && length(varargin{2})==1 0117 n = varargin{2}; 0118 dom = [-2*pi, 2*pi]; 0119 color = 'red'; 0120 elseif isa(varargin{2},'char') 0121 dom = [-2*pi, 2*pi]; 0122 n = 60; 0123 color = varargin{2}; 0124 end 0125 case 3 % If more than 2 arguments are given, it's 0126 f = varargin{1}; % assumed they are in the correct order 0127 dom = varargin{2}; 0128 n = varargin{3}; 0129 color = 'red'; % default color 0130 case 4 % If more than 2 arguments are given, it's 0131 f = varargin{1}; % assumed they are in the correct order 0132 dom = varargin{2}; 0133 n = varargin{3}; 0134 color = varargin{4}; 0135 otherwise 0136 warning('Ezimplot3:Arguments', ... 0137 'Attempt will be made only with the 4 first arguments'); 0138 f = varargin{1}; 0139 dom = varargin{2}; 0140 n = varargin{3}; 0141 color = varargin{4}; 0142 end 0143 if length(dom) == 2 0144 dom = repmat(dom,1,3); %domain repeated in all variables 0145 elseif length(dom) ~= 6 0146 error('Ezimplot3:Arguments',... 0147 'Input argument "domain" must be a row vector of size 2 or size 6'); 0148 end 0149 % 0150 %-------------------------------------------- 0151 function [f_hand f_text] = fix_fun(fun) 0152 % FIX_FUN(fun) Converts "fun" into an anonymous function of 3 variables (x,y,z) 0153 % with handle "f_hand" and a string "f_text" to use it as title 0154 types = {'char','sym','function_handle','inline'}; % cell array of 'types' 0155 type = ''; %Identifing FUN object class 0156 for i=1:size(types,2) 0157 if isa(fun,types{i}) 0158 type = types{i}; 0159 break; 0160 end 0161 end 0162 switch type 0163 case 'char' % Formatting FUN if it is char type. There's 2 possibilities: 0164 % A string with the name of the .m file 0165 if exist([fun,'.m'],'file') 0166 syms x y z; 0167 if nargin(str2func(fun)) == 3 0168 f_sym = eval([fun,'(x,y,z)']); % evaluating FUN at the sym point (x,y,z) 0169 else 0170 error('Ezimplot3:Arguments',... 0171 '%s must be a function of 3 arguments or unknown function',fun); 0172 end 0173 f_text = strrep(char(f_sym),' ',''); % converting to char and eliminating spaces 0174 f_hand = eval(['@(x,y,z)',vectorize(f_text),';']); % converting string to anonymous f_handle 0175 else 0176 % A string with the function's expression 0177 f_hand = eval(['@(x,y,z)',vectorize(fun),';']); % converting string to anonymous f_handle 0178 f_text = strrep(fun,'.',''); f_text = strrep(f_text,' ',''); % removing vectorization & spaces 0179 end 0180 case 'sym' % Formatting FUN if it is a symbolic object 0181 f_hand = eval(['@(x,y,z)',vectorize(fun),';']); % converting string to anonymous f_handle 0182 f_text = strrep(char(fun),' ',''); % removing spaces 0183 case {'function_handle', 'inline'} % Formatting FUN if it is a function_handle or an inline object 0184 syms x y z; 0185 if nargin(fun) == 3 %&& numel(symvar(char(fun))) == 3 % Determining if # variables == 3 0186 f_sym = fun(x,y,z); % evaluating FUN at the sym point (x,y,z) 0187 else 0188 error('Ezimplot3:Arguments',... 0189 '%s must be function of 3 arguments or unknown function',char(fun)); 0190 end 0191 f_text = strrep(char(f_sym),' ',''); % converting into string to removing spaces 0192 f_hand = eval(['@(x,y,z)',vectorize(f_text),';']); % converting string to anonymous f_handle 0193 otherwise 0194 error('First argument "fun" must be of type character, simbolic, function handle or inline'); 0195 end