]> Creatis software - CreaPhase.git/blob - octave_packages/m/plot/isonormals.m
update packages
[CreaPhase.git] / octave_packages / m / plot / isonormals.m
1 ## Copyright (C) 2009-2012 Martin Helm
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 ## -*- texinfo -*-
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})
26 ##
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.
34 ##
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
39 ## function.
40 ##
41 ## If given the string input argument "negate" as last input argument
42 ## then compute the reverse vector normals of an isosurface geometry.
43 ##
44 ## If no output argument is given then directly redraw the patch that is
45 ## given by the patch handle @var{p}.
46 ##
47 ## For example:
48 ## @c Set example in small font to prevent overfull line
49 ##
50 ## @smallexample
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
58 ## endfunction
59 ##
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
66 ##
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
72 ##
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
77 ## isofinish (p);
78 ##
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
84 ## isofinish (p);
85 ##
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
90 ## isofinish (p);
91 ## @end smallexample
92 ##
93 ## @seealso{isosurface, isocolors}
94 ## @end deftypefn
95
96 ## Author: Martin Helm <martin@mhelm.de>
97
98 function varargout = isonormals(varargin)
99   na = nargin;
100   negate = false;
101   if (ischar (varargin{nargin}))
102     na = nargin-1;
103     if (strcmp (lower (varargin{nargin}), "negate"))
104       negate = true;
105     else
106       error ("isonormals: Unknown option '%s'", varargin{nargin});
107     endif
108   endif
109   switch (na)
110     case 2
111       c = varargin{1};
112       vp = varargin{2};
113       x = 1:size (c, 2);
114       y = 1:size (c, 1);
115       z = 1:size (c, 3);
116     case 5
117       x = varargin{1};
118       y = varargin{2};
119       z = varargin{3};
120       c = varargin{4};
121       vp = varargin{5};
122     otherwise
123       print_usage ();
124   endswitch
125   if (ismatrix (vp) && size (vp,2) == 3)
126     pa = [];
127     v = vp;
128   elseif (ishandle (vp))
129     pa = vp;
130     v = get (pa, "Vertices");
131   else
132     error ("isonormals: Last argument is not a vertex list or a patch handle");
133   endif
134   if (negate)
135     normals = -__interp_cube__ (x, y, z, c, v, "normals");
136   else
137     normals = __interp_cube__ (x, y, z, c, v, "normals");
138   endif
139   switch (nargout)
140     case 0
141       if (!isempty (pa))
142         set (pa, "VertexNormals", normals);
143       endif
144     case 1
145       varargout = {normals};
146     otherwise
147       print_usage ();
148   endswitch
149 endfunction
150
151 %!test
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));
157 %!test
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));