7337
|
1 ## Copyright (C) 2007 David Bateman |
|
2 ## |
|
3 ## This file is part of Octave. |
|
4 ## |
|
5 ## Octave is free software; you can redistribute it and/or modify it |
|
6 ## under the terms of the GNU General Public License as published by |
|
7 ## the Free Software Foundation; either version 3 of the License, or (at |
|
8 ## your option) any later version. |
|
9 ## |
|
10 ## Octave is distributed in the hope that it will be useful, but |
|
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 ## General Public License for more details. |
|
14 ## |
|
15 ## You should have received a copy of the GNU General Public License |
|
16 ## along with Octave; see the file COPYING. If not, see |
|
17 ## <http://www.gnu.org/licenses/>. |
|
18 |
|
19 ## Undocumented internal function |
|
20 |
|
21 function [h, needusage] = __ezplot__ (pfunc, varargin) |
|
22 |
|
23 func = strcat ("ez", pfunc); |
|
24 if (strncmp (pfunc, "contour", 7)) |
|
25 iscontour = true; |
|
26 else |
|
27 iscontour = false; |
|
28 endif |
|
29 if (strcmp (pfunc, "plot3")) |
|
30 isplot3 = true; |
|
31 ispolar = false; |
|
32 nargs = 1 |
|
33 elseif (strcmp (pfunc, "polar")) |
|
34 isplot3 = false; |
|
35 ispolar = true; |
|
36 nargs = 1; |
|
37 else |
|
38 isplot3 = false; |
|
39 ispolar = false; |
|
40 nargs = 2; |
|
41 endif |
|
42 |
|
43 [ax, varargin, nargin] = __plt_get_axis_arg__ (func, varargin{:}); |
|
44 |
|
45 needusage = false; |
|
46 if (nargin < 1) |
|
47 needusage = true; |
|
48 return; |
|
49 endif |
|
50 |
|
51 parametric = false; |
|
52 fun = varargin {1}; |
|
53 if (ischar (fun)) |
|
54 fun = vectorize (inline (fun)); |
|
55 if (length (argnames (fun)) != nargs) |
|
56 error ("%s: excepting a function of %d arguments", func, nargs); |
|
57 endif |
|
58 fstr = formula (fun); |
|
59 if (isplot3) |
|
60 xarg = "x"; |
|
61 yarg = "y"; |
|
62 elseif (ispolar) |
|
63 xarg = ""; |
|
64 yarg = ""; |
|
65 else |
|
66 xarg = argnames(fun){1}; |
|
67 yarg = argnames(fun){2}; |
|
68 endif |
|
69 elseif (strcmp (typeinfo (fun), "inline function")) |
|
70 if (length (argnames (fun)) != nargs) |
|
71 error ("%s: excepting a function of %d arguments", func, nargs); |
|
72 endif |
|
73 fun = vectorize (fun); |
|
74 fstr = formula (fun); |
|
75 if (isplot3) |
|
76 xarg = "x"; |
|
77 yarg = "y"; |
|
78 elseif (ispolar) |
|
79 xarg = ""; |
|
80 yarg = ""; |
|
81 else |
|
82 xarg = argnames(fun)(1); |
|
83 yarg = argnames(fun)(2); |
|
84 endif |
|
85 elseif (isa (fun, "function_handle")) |
|
86 fstr = func2str (fun); |
|
87 args = regexp (substr (fstr, 3, findstr (fstr, ")")(1) - 3), |
|
88 '(\w[\w\d]*)', 'tokens'); |
|
89 if (length (args) != nargs) |
|
90 error ("%s: excepting a function of %d arguments", func, nargs); |
|
91 endif |
|
92 fstr = substr (fstr, findstr (fstr, ")")(1) + 1); |
|
93 if (isplot3) |
|
94 xarg = "x"; |
|
95 yarg = "y"; |
|
96 elseif (ispolar) |
|
97 xarg = ""; |
|
98 yarg = ""; |
|
99 else |
|
100 xarg = args{1}{1}; |
|
101 yarg = args{2}{1}; |
|
102 endif |
|
103 else |
|
104 error ("%s: expecting string, inline function or function handle", func); |
|
105 endif |
|
106 |
|
107 if (nargin > 2) |
|
108 funx = fun; |
|
109 fstrx = fstr; |
|
110 funy = varargin {2}; |
|
111 if (ischar (funy) && ! strcmp (funy, "circ") && ! strcmp (funy, "animate")) |
|
112 parametric = true; |
|
113 funy = vectorize (inline (funy)); |
|
114 if (length (argnames (funy)) != nargs) |
|
115 error ("%s: excepting a function of %d arguments", func, nargs); |
|
116 endif |
|
117 fstry = formula (funy); |
|
118 elseif (strcmp (typeinfo (funy), "inline function")) |
|
119 parametric = true; |
|
120 if (length (argnames (funy)) != nargs) |
|
121 error ("%s: excepting a function of %d arguments", func, nargs); |
|
122 endif |
|
123 funy = vectorize (funy); |
|
124 fstry = formula (funy); |
|
125 elseif (isa (funy, "function_handle")) |
|
126 parametric = true; |
|
127 fstry = func2str (funy); |
|
128 args = regexp (substr (fstry, 3, findstr (fstry, ")")(1) - 3), |
|
129 '(\w[\w\d]*)', 'tokens'); |
|
130 if (length (args) != nargs) |
|
131 error ("%s: excepting a function of %d arguments", func, nargs); |
|
132 endif |
|
133 fstry = substr (fstry, findstr (fstry, ")")(1) + 1); |
|
134 endif |
|
135 |
|
136 if (parametric) |
|
137 funz = varargin {3}; |
|
138 if (ischar (funz) && ! strcmp (funz, "circ") && |
|
139 ! strcmp (funy, "animate")) |
|
140 funz = vectorize (inline (funz)); |
|
141 if (length (argnames (funz)) != nargs) |
|
142 error ("%s: excepting a function of %d arguments", func, nargs); |
|
143 endif |
|
144 fstrz = formula (funz); |
|
145 elseif (strcmp (typeinfo (funz), "inline function")) |
|
146 if (length (argnames (funz)) != nargs) |
|
147 error ("%s: excepting a function of %d arguments", func, nargs); |
|
148 endif |
|
149 funz = vectorize (funz); |
|
150 fstrz = formula (funz); |
|
151 elseif (isa (funz, "function_handle")) |
|
152 fstrz = func2str (funz); |
|
153 args = regexp (substr (fstrz, 3, findstr (fstrz, ")")(1) - 3), |
|
154 '(\w[\w\d]*)', 'tokens'); |
|
155 if (length (args) != nargs) |
|
156 error ("%s: excepting a function of %d arguments", func, nargs); |
|
157 endif |
|
158 fstrz = substr (fstrz, findstr (fstrz, ")")(1) + 1); |
|
159 else |
|
160 error ("%s: parametric plots expect 3 functions", func); |
|
161 endif |
|
162 endif |
|
163 endif |
|
164 |
|
165 n = 60; |
|
166 domain = []; |
|
167 circ = false; |
|
168 animate = false; |
|
169 if (parametric) |
|
170 iarg = 4; |
|
171 else |
|
172 iarg = 2; |
|
173 endif |
|
174 while (iarg <= nargin) |
|
175 arg = varargin{iarg++}; |
|
176 if (ischar (arg) && strcmp (arg, "circ")) |
|
177 circ = true; |
|
178 elseif (ischar (arg) && strcmp (arg, "animate")) |
|
179 animate = true; |
|
180 elseif (isscalar (arg)) |
|
181 n = arg; |
|
182 elseif (numel (arg) == 2) |
|
183 domain = [arg(:).' arg(:).']; |
|
184 elseif (numel (arg) == 4) |
|
185 domain = arg(:).'; |
|
186 else |
|
187 error ("%s: expecting scalar, 2 or 4 element vector", func); |
|
188 endif |
|
189 endwhile |
|
190 |
|
191 if (isempty (domain)) |
|
192 if (isplot3 || ispolar) |
|
193 domain = [0, 2*pi, 0, 2*pi]; |
|
194 else |
|
195 domain = [-2*pi, 2*pi, -2*pi, 2*pi]; |
|
196 endif |
|
197 endif |
|
198 |
|
199 if (circ) |
|
200 if (iscontour || isplot3) |
|
201 needusage = true; |
|
202 return; |
|
203 endif |
|
204 if (parametric) |
|
205 error ("%s: can not have both circular domain and parametric function", |
|
206 func); |
|
207 endif |
|
208 cent = [domain(1) + domain(2), domain(3) + domain(4)] / 2; |
|
209 funx = @(r,t) r .* cos (t) + cent (1); |
|
210 funy = @(r,t) r .* sin (t) + cent (2); |
|
211 domain = [0, sqrt((domain(2) - cent(1))^2 + (domain(4) - cent(2))^2), ... |
|
212 -pi, pi]; |
|
213 funz = fun; |
|
214 parametric = true; |
|
215 endif |
|
216 |
|
217 if (animate) |
|
218 if (!isplot3) |
|
219 error ("%s: animated graphs only valid with plot3", func); |
|
220 endif |
|
221 error ("%s: animated graphs not implemented", func); |
|
222 endif |
|
223 |
|
224 if (isplot3 || ispolar) |
|
225 X = linspace (domain (1), domain (2), n); |
|
226 else |
|
227 x = linspace (domain (1), domain (2), n); |
|
228 y = linspace (domain (3), domain (4), n); |
|
229 [X, Y] = meshgrid (x, y); |
|
230 endif |
|
231 if (parametric) |
|
232 if (isplot3) |
|
233 Z = feval (funz, X); |
|
234 XX = feval (funx, X); |
|
235 YY = feval (funy, X); |
|
236 X = XX; |
|
237 Y = YY; |
|
238 else |
|
239 Z = feval (funz, X, Y); |
|
240 XX = feval (funx, X, Y); |
|
241 YY = feval (funy, X, Y); |
|
242 X = XX; |
|
243 Y = YY; |
|
244 |
|
245 ## Eliminate the singularities |
|
246 X = __eliminate_sing__ (X); |
|
247 Y = __eliminate_sing__ (Y); |
|
248 Z = __eliminate_sing__ (Z); |
|
249 endif |
|
250 |
|
251 fstrx = regexprep (regexprep (regexprep (fstrx,'\.\^\s*','^'), |
|
252 '\./', '/'), '[\.]*\*', ''); |
|
253 fstry = regexprep (regexprep (regexprep (fstry,'\.\^\s*','^'), |
|
254 '\./', '/'), '[\.]*\*', ''); |
|
255 fstrz = regexprep (regexprep (regexprep (fstrz,'\.\^\s*','^'), |
|
256 '\./', '/'), '[\.]*\*', ''); |
|
257 fstr = strcat ("[",fstrx,",",fstry,",",fstrz,"]"); |
|
258 else |
|
259 if (isplot3) |
|
260 needusage = true; |
|
261 return; |
|
262 endif |
|
263 |
|
264 if (ispolar) |
|
265 Z = feval (fun, X); |
|
266 else |
|
267 Z = feval (fun, X, Y); |
|
268 |
|
269 ## Eliminate the singularities |
|
270 Z = __eliminate_sing__ (Z); |
|
271 endif |
|
272 |
|
273 fstr = regexprep (regexprep (regexprep (fstr,'\.\^\s*','^'), '\./', '/'), |
|
274 '[\.]*\*', ''); |
|
275 endif |
|
276 |
|
277 oldax = gca (); |
|
278 unwind_protect |
|
279 axes (ax); |
|
280 if (iscontour) |
|
281 [clev, h] = feval (pfunc, X, Y, Z); |
|
282 elseif (ispolar) |
|
283 h = feval (pfunc, X, Z); |
|
284 else |
|
285 h = feval (pfunc, X, Y, Z); |
|
286 endif |
|
287 xlabel (xarg); |
|
288 ylabel (yarg); |
|
289 title (fstr); |
|
290 unwind_protect_cleanup |
|
291 axes (oldax); |
|
292 end_unwind_protect |
|
293 |
|
294 endfunction |
|
295 |
|
296 function x = __eliminate_sing__ (x) |
|
297 x (isinf (x)) = NaN; |
|
298 x (abs (del2 (x)) > 0.2 * (max(x(:)) - min(x(:)))) = NaN; |
|
299 endfunction |