1 ## Copyright (C) 2002-2009 Etienne Grossmann <etienne@egdn.net>
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
16 ## s = vmesh (x, y, z [, options] ) - Visualize a 3D surface
17 ## s = vmesh (z [, options] )
19 ## Visualizes a 3D surface. Returns the VRML code.
21 ## x : RxC or C : X coordinates of the points on the surface
22 ## y : RxC or R : Y " "
25 ## s : string : The code
27 ## If x and y are omitted, they are assumed to be linspace(-1,1,C or R).
28 ## Points presenting one or more 'inf' or 'nan' coordinates are ignored.
30 ## Options : (all options of vrml_surf may be used too)
32 ## "col" , col : 3 : RGB Color, Default = [0.3,0.4,0.9]
33 ## or 3x(R*C): Color of vertices (vrml colorPerVertex is TRUE).
36 ## or 1 : Reflectivity (equivalent to [col,col,col] in RGB)
37 ## or R x C : Reflectivity of vertices
41 ## : Reflectivity of facets.
43 ## RGB and reflectivity values should be in the [0,1] interval.
45 ## "checker", c : 1x2 : Color as a checker. If c(1) is positive, checker has
46 ## c(1) rows. If it is negative, each checker row is
47 ## c(1) facets high. c(2) does the same for columns.
48 ## or 1x1 : Same as [c,c].
50 ## "zgray" : Color varies from black for lowest point to white
53 ## "zrb" : Color varies from blue for lowest point to red for
56 ## "zcol", zcol : Mx3 : Color is linearly interpolated between the RGB
57 ## values specified by the rows of zcol.
59 ## "steps" : Represent surface as a piecewise constant Z = f(X,Y)
62 ## "bars" : Represent surface as a bar plot
63 ## "bwid" : Bar width, relative to point separation. Default = 2/3
65 ## "level", l : 1xN : Display one or more horizontal translucent plane(s)
67 ## z == l(i) (1 <= i <= length(l))
69 ## "lcol", lc : Nx3 : Color of the plane(s). Default = [.7 .7 .7]
70 ## "ltran",lt : Nx1 : Transparency of the plane(s). Default = 0.3
73 ## "normalize" : Normalize z to [-1,1]
75 ## See also: vrml_surf(), vrml_faces(), demo("vmesh")
77 function s = vmesh (x, y, z, varargin)
84 if (nargin <= 1) || ischar(y), # Cruft to allow not passing x and y
87 [xx,yy] = meshgrid (linspace (-1,1,C), linspace (-1,1,R));
90 varargin = {y, z, varargin{:}};
92 varargin = {y, varargin{:}};
95 ## s = vmesh ( xx, yy, zz, y, z, varargin{:} );
96 ## if ! nargout, clear s; end; return
98 ## s = vmesh ( xx, yy, zz, y, varargin{:} );
99 ## if ! nargout, clear s; end; return
101 x = xx ; y = yy ; z = zz ;
106 ## surf_args = list (x,y,z); # Arguments that'll be passed to vrml_surf
107 surf_args = {x,y,z}; # Arguments that'll be passed to vrml_surf
111 op1 = [" tran col checker creaseAngle emit colorPerVertex tex zcol frame ",\
112 " level lcol ltran bwid "];
113 op0 = " smooth zgray zrb normalize steps bars ";
115 df = tars (level, lcol, ltran, normalize, frame);
117 opts = read_options (varargin,"op0",op0,"op1",op1,"default",df);
119 # Identify options for vrml_surf()
120 # all_surf_opts = list ("tran", "col", "checker", "creaseAngle", "emit", \
121 # "colorPerVertex", "smooth", "tex",\
122 # "zgray","zrb","zcol");
123 all_surf_opts = {"tran", "col", "checker", "creaseAngle", "emit", \
124 "colorPerVertex", "smooth", "steps", "bars", "bwid", "tex",\
125 "zgray","zrb","zcol"};
127 for i = 1:length(all_surf_opts)
128 optname = all_surf_opts{i};
129 if isfield (opts, optname)
130 ## surf_args = append (surf_args, list (optname));
131 surf_args{length(surf_args)+1} = optname;
132 if index (op1,[" ",optname," "])
133 ## surf_args = append (surf_args, list(opts.(optname)));
134 surf_args{length(surf_args)+1} = opts.(optname);
142 normalize = opts.normalize;
150 datascl = nanmax (abs([z(:);y(:);x(:)]));
155 # Put back z in surf_args
161 s = vrml_surf (surf_args{:});
163 if numel (x) == columns (z)
164 x = ones(rows(z),1) * x(:)';
166 assert (numel (x) == numel (z));
168 if numel (y) == rows (z)
169 y = y(:) * ones(1,columns(z));
171 assert (numel (y) == numel (z));
174 pts = [x(:)';y(:)';z(:)'];
175 ii = find (all (isfinite (pts)));
176 pt2 = pts(:,ii); x2 = x(ii); y2 = y(ii); z2 = z(ii);
180 # scl = max (max(pt2') - min(pt2'));
182 # lpos = [min(x2) - 0.5*scl, mean(y2), max(z2)+scl]
183 # pl1 = vrml_PointLight ("location", lpos, "intensity", 0.7);
185 # lpos = [mean(x2), min(y2) - 0.5*scl, max(z2)+scl]
186 # pl2 = vrml_PointLight ("location", lpos, "intensity", 0.7);
190 pl = [vrml_DirectionalLight("direction",[-1,-1,-1],"intensity",0.75),\
191 vrml_DirectionalLight("direction",[-1, 1,-1],"intensity",0.5),\
192 vrml_DirectionalLight("direction",[ 1,-1,-1],"intensity",0.5),\
193 vrml_DirectionalLight("direction",[ 1, 1,-1],"intensity",0.33),\
194 vrml_DirectionalLight("direction",[ 0, 0, 1],"intensity",0.5)];
196 # distance = max ([max (x(:)) - min (x(:)),\
197 # max (y(:)) - min (y(:)),\
198 # max (z(:)) - min (z(:))])
199 # vp = vrml_Viewpoint ("orientation", [1 0 0 -pi/6],\
200 # "position", distance*[0 0 5]);
204 medpts = (minpts + maxpts)/2;
205 ptssz = (maxpts - minpts);
206 ptssz = max (ptssz, max (ptssz/10));
208 if frame, fr = vrml_frame (minpts-ptssz/10,\
209 "scale", ptssz * 1.2, "col",(ones(3)+eye(3))/2);
213 sbg = vrml_Background ("skyColor", [0.5 0.5 0.6]);
217 level = level(:)'; # Make a row
218 nlev = length (level);
220 xmin = min (x(:)); xmax = max (x(:));
221 ymin = min (y(:)); ymax = max (y(:));
223 if any (size (lcol) != [nlev,3])
224 nlc = prod (szlc = size (lcol));
226 if all (szlc == [3,nlev]), lcol = lcol';
228 elseif nlc == 1 , lcol = lcol * ones (nlev,3);
230 elseif nlc == nlev , lcol = lcol(:)*[1 1 1];
231 elseif nlc == 3 , lcol = ones(nlev,1)*lcol(:)';
232 else error ("lcol has size %i x %i",szlc);
235 if prod (size (ltran)) == 1 , ltran = ltran*ones(1,nlev); end
239 vrml_parallelogram([xmin xmin xmax xmax;\
240 ymin ymax ymax ymin;\
241 level(i) level(i) level(i) level(i)],\
242 "col",lcol(i,:),"tran",ltran(i))];
246 s = [pl, sbg, s , fr, slevel];
256 %! % Test the vmesh and vrml_browse functions with the test_vmesh script
258 %! [x,y] = meshgrid (linspace (-8+eps,8+eps,C), linspace (-8+eps,8+eps,R));
259 %! z = sin (sqrt (x.^2 + y.^2)) ./ (sqrt (x.^2 + y.^2));
261 %! printf ("Press a key.\n"); pause;
263 %! ############## The same surface, with holes (NaN's) in it. ###############
264 %! z(3,3) = nan; # Bore a hole
266 %! z(1+floor(rand(1,5+R*C/30)*R*C)) = nan;
268 %! printf ("Press a key.\n"); pause;
270 %! ###### The same surface, with checkered stripes - 'checker' option ######
271 %! vmesh (z,"checker",-[6,5]);
272 %! printf ("Press a key.\n"); pause;
274 %! ##### With z-dependent coloring - 'zrb', 'zgray' and'zcol' options. #####
276 %! printf ("That's it!\n");