1 ## Copyright (C) 2009-2012 Martin Helm
3 ## This file is part of Octave.
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.
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.
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/>.
20 ## @deftypefn {Function File} {[@var{n}] =} isonormals (@var{val}, @var{v})
21 ## @deftypefnx {Function File} {[@var{n}] =} isonormals (@var{val}, @var{p})
22 ## @deftypefnx {Function File} {[@var{n}] =} isonormals (@var{x}, @var{y}, @var{z}, @var{val}, @var{v})
23 ## @deftypefnx {Function File} {[@var{n}] =} isonormals (@var{x}, @var{y}, @var{z}, @var{val}, @var{p})
24 ## @deftypefnx {Function File} {[@var{n}] =} isonormals (@dots{}, "negate")
25 ## @deftypefnx {Function File} {} isonormals (@dots{}, @var{p})
27 ## If called with one output argument and the first input argument
28 ## @var{val} is a three-dimensional array that contains the data for an
29 ## isosurface geometry and the second input argument @var{v} keeps the
30 ## vertices of an isosurface then return the normals @var{n} in form of
31 ## a matrix with the same size than @var{v} at computed points
32 ## @command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}. The output argument
33 ## @var{n} can be taken to manually set @var{VertexNormals} of a patch.
35 ## If called with further input arguments @var{x}, @var{y} and @var{z}
36 ## which are three--dimensional arrays with the same size than @var{val}
37 ## then the volume data is taken at those given points. Instead of the
38 ## vertices data @var{v} a patch handle @var{p} can be passed to this
41 ## If given the string input argument "negate" as last input argument
42 ## then compute the reverse vector normals of an isosurface geometry.
44 ## If no output argument is given then directly redraw the patch that is
45 ## given by the patch handle @var{p}.
48 ## @c Set example in small font to prevent overfull line
51 ## function [] = isofinish (p)
52 ## set (gca, "PlotBoxAspectRatioMode", "manual", ...
53 ## "PlotBoxAspectRatio", [1 1 1]);
54 ## set (p, "VertexNormals", -get (p,"VertexNormals")); # Revert normals
55 ## set (p, "FaceColor", "interp");
56 ## ## set (p, "FaceLighting", "phong");
57 ## ## light ("Position", [1 1 5]); # Available with JHandles
60 ## N = 15; # Increase number of vertices in each direction
61 ## iso = .4; # Change isovalue to .1 to display a sphere
62 ## lin = linspace (0, 2, N);
63 ## [x, y, z] = meshgrid (lin, lin, lin);
64 ## c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
65 ## figure (); # Open another figure window
67 ## subplot (2,2,1); view (-38, 20);
68 ## [f, v, cdat] = isosurface (x, y, z, c, iso, y);
69 ## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, ...
70 ## "FaceColor", "interp", "EdgeColor", "none");
71 ## isofinish (p); ## Call user function isofinish
73 ## subplot (2,2,2); view (-38, 20);
74 ## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, ...
75 ## "FaceColor", "interp", "EdgeColor", "none");
76 ## isonormals (x, y, z, c, p); # Directly modify patch
79 ## subplot (2,2,3); view (-38, 20);
80 ## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, ...
81 ## "FaceColor", "interp", "EdgeColor", "none");
82 ## n = isonormals (x, y, z, c, v); # Compute normals of isosurface
83 ## set (p, "VertexNormals", n); # Manually set vertex normals
86 ## subplot (2,2,4); view (-38, 20);
87 ## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", cdat, ...
88 ## "FaceColor", "interp", "EdgeColor", "none");
89 ## isonormals (x, y, z, c, v, "negate"); # Use reverse directly
93 ## @seealso{isosurface, isocolors}
96 ## Author: Martin Helm <martin@mhelm.de>
98 function varargout = isonormals(varargin)
101 if (ischar (varargin{nargin}))
103 if (strcmp (lower (varargin{nargin}), "negate"))
106 error ("isonormals: Unknown option '%s'", varargin{nargin});
125 if (ismatrix (vp) && size (vp,2) == 3)
128 elseif (ishandle (vp))
130 v = get (pa, "Vertices");
132 error ("isonormals: Last argument is not a vertex list or a patch handle");
135 normals = -__interp_cube__ (x, y, z, c, v, "normals");
137 normals = __interp_cube__ (x, y, z, c, v, "normals");
142 set (pa, "VertexNormals", normals);
145 varargout = {normals};
152 %! [x, y, z] = meshgrid (0:.5:2, 0:.5:2, 0:.5:2);
153 %! c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
154 %! [f, v, cdat] = isosurface (x, y, z, c, .4, y);
155 %! n = isonormals (x, y, z, c, v);
156 %! assert (size (v), size (n));
158 %! [x, y, z] = meshgrid (0:.5:2, 0:.5:2, 0:.5:2);
159 %! c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2);
160 %! [f, v, cdat] = isosurface (x, y, z, c, .4, y);
161 %! np = isonormals (x, y, z, c, v);
162 %! nn = isonormals (x, y, z, c, v, "negate");
163 %! assert (all (np == -nn));