Mercurial > hg > octave-nkf
comparison scripts/plot/isosurface.m @ 9110:22ae6b3411a7
Add isocolor, isonormals and isosurface functions (For Martin Helm). Add 3D filled triangular patches and the trisurf function
author | David Bateman <dbateman@free.fr> |
---|---|
date | Sat, 11 Apr 2009 16:26:01 +0200 |
parents | |
children | 09da0bd91412 |
comparison
equal
deleted
inserted
replaced
9109:978c863bc8e5 | 9110:22ae6b3411a7 |
---|---|
1 ## Copyright (C) 2009 Martin Helm | |
2 ## | |
3 ## This program is free software; you can redistribute it and/or modify | |
4 ## it under the terms of the GNU General Public License as published by | |
5 ## the Free Software Foundation; either version 3 of the License, or | |
6 ## (at your option) any later version. | |
7 ## | |
8 ## This program is distributed in the hope that it will be useful, | |
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 ## GNU General Public License for more details. | |
12 ## | |
13 ## You should have received a copy of the GNU General Public License | |
14 ## along with this program; if not, see http://www.gnu.org/licenses/gpl.html. | |
15 | |
16 ## -*- texinfo -*- | |
17 ## @deftypefn {Function File} {[@var{fv}] =} isosurface (@var{val}, @var{iso}) | |
18 ## @deftypefnx {Function File} {[@var{fv}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}) | |
19 ## @deftypefnx {Function File} {[@var{fv}] =} isosurface (@dots{}, "noshare", "verbose") | |
20 ## @deftypefnx {Function File} {[@var{fvc}] =} isosurface (@dots{}, @var{col}) | |
21 ## @deftypefnx {Function File} {[@var{f}, @var{v}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}) | |
22 ## @deftypefnx {Function File} {[@var{f}, @var{v}, @var{c}] =} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}) | |
23 ## @deftypefnx {Function File} {} isosurface (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}, @var{opt}) | |
24 ## | |
25 ## If called with one output argument and the first input argument | |
26 ## @var{val} is a three--dimensional array that contains the data of an | |
27 ## isosurface geometry and the second input argument @var{iso} keeps the | |
28 ## isovalue as a scalar value then return a structure array @var{fv} | |
29 ## that contains the fields @var{Faces} and @var{Vertices} at computed | |
30 ## points @command{[x, y, z] = meshgrid (1:l, 1:m, 1:n)}. The output | |
31 ## argument @var{fv} can directly be taken as an input argument for the | |
32 ## @command{patch} function. | |
33 ## | |
34 ## If called with further input arguments @var{x}, @var{y} and @var{z} | |
35 ## which are three--dimensional arrays with the same size than @var{val} | |
36 ## then the volume data is taken at those given points. | |
37 ## | |
38 ## The string input argument "noshare" is only for compatibility and | |
39 ## has no effect. If given the string input argument | |
40 ## "verbose" then print messages to the command line interface about the | |
41 ## current progress. | |
42 ## | |
43 ## If called with the input argument @var{col} which is a | |
44 ## three-dimensional array of the same size than @var{val} then take | |
45 ## those values for the interpolation of coloring the isosurface | |
46 ## geometry. Add the field @var{FaceVertexCData} to the structure | |
47 ## array @var{fv}. | |
48 ## | |
49 ## If called with two or three output arguments then return the | |
50 ## information about the faces @var{f}, vertices @var{v} and color data | |
51 ## @var{c} as seperate arrays instead of a single structure array. | |
52 ## | |
53 ## If called with no output argument then directly process the | |
54 ## isosurface geometry with the @command{patch} command. | |
55 ## | |
56 ## For example | |
57 ## | |
58 ## @example | |
59 ## [x, y, z] = meshgrid (1:5, 1:5, 1:5); | |
60 ## val = rand (5, 5, 5); | |
61 ## isosurface (x, y, z, val, .5); | |
62 ## @end example | |
63 ## | |
64 ## will directly draw a random isosurface geometry in a graphics window. | |
65 ## Another example for an isosurface geometry with different additional | |
66 ## coloring | |
67 ## | |
68 ## @example | |
69 ## N = 15; ## Increase number of vertices in each direction | |
70 ## iso = .4; ## Change isovalue to .1 to display a sphere | |
71 ## lin = linspace (0, 2, N); | |
72 ## [x, y, z] = meshgrid (lin, lin, lin); | |
73 ## c = abs ((x-.5).^2 + (y-.5).^2 + (z-.5).^2); | |
74 ## figure (); ## Open another figure window | |
75 ## | |
76 ## subplot (2, 2, 1); view (-38, 20); | |
77 ## [f, v] = isosurface (x, y, z, c, iso); | |
78 ## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "none"); | |
79 ## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]); | |
80 ## # set (p, "FaceColor", "green", "FaceLighting", "phong"); | |
81 ## # light ("Position", [1 1 5]); ## Available with the JHandles package | |
82 ## | |
83 ## subplot (2, 2, 2); view (-38, 20); | |
84 ## p = patch ("Faces", f, "Vertices", v, "EdgeColor", "blue"); | |
85 ## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]); | |
86 ## # set (p, "FaceColor", "none", "FaceLighting", "phong"); | |
87 ## # light ("Position", [1 1 5]); | |
88 ## | |
89 ## subplot (2, 2, 3); view (-38, 20); | |
90 ## [f, v, c] = isosurface (x, y, z, c, iso, y); | |
91 ## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \ | |
92 ## "FaceColor", "interp", "EdgeColor", "none"); | |
93 ## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]); | |
94 ## # set (p, "FaceLighting", "phong"); | |
95 ## # light ("Position", [1 1 5]); | |
96 ## | |
97 ## subplot (2, 2, 4); view (-38, 20); | |
98 ## p = patch ("Faces", f, "Vertices", v, "FaceVertexCData", c, \ | |
99 ## "FaceColor", "interp", "EdgeColor", "blue"); | |
100 ## set (gca, "DataAspectRatioMode","manual", "DataAspectRatio", [1 1 1]); | |
101 ## # set (p, "FaceLighting", "phong"); | |
102 ## # light ("Position", [1 1 5]); | |
103 ## @end example | |
104 ## | |
105 ## @seealso{isocolors, isonormals, isocaps} | |
106 ## | |
107 ## @end deftypefn | |
108 | |
109 ## Author: Martin Helm <martin@mhelm.de> | |
110 | |
111 function varargout = isosurface(varargin) | |
112 | |
113 if (nargin < 2 || nargin > 8 || nargout > 3) | |
114 print_usage (); | |
115 endif | |
116 | |
117 calc_colors = false; | |
118 f = v = c = []; | |
119 verbose = false; | |
120 noshare = false; | |
121 if (nargin >= 5) | |
122 x = varargin{1}; | |
123 y = varargin{2}; | |
124 z = varargin{3}; | |
125 val = varargin{4}; | |
126 iso = varargin{5}; | |
127 if (nargin >= 6 && ismatrix (varargin{6})) | |
128 colors = varargin{6}; | |
129 calc_colors = true; | |
130 endif | |
131 else | |
132 val = varargin{1}; | |
133 [n1, n2, n3] = size (val); | |
134 [x, y, z] = meshgrid (1:n1, 1:n2, 1:n3); | |
135 iso = varargin{2}; | |
136 if (nargin >= 3 && ismatrix (varargin{3})) | |
137 colors = varargin{3}; | |
138 calc_colors = true; | |
139 endif | |
140 endif | |
141 if (calc_colors) | |
142 if (nargout == 2) | |
143 warning ( "Colors will be calculated, but you did not specify an output argument for it!" ); | |
144 endif | |
145 [fvc.faces, fvc.vertices, fvc.facevertexcdata] = __marching_cube__ (x, y, z, val, iso, colors); | |
146 else | |
147 [fvc.faces, fvc.vertices] = __marching_cube__ (x, y, z, val, iso); | |
148 endif | |
149 | |
150 if (isempty (fvc.vertices) || isempty (fvc.faces)) | |
151 warning ( "The resulting triangulation is empty" ); | |
152 endif | |
153 | |
154 switch (nargout) | |
155 case 0 | |
156 ## plot the calculated surface | |
157 newplot (); | |
158 if (calc_colors) | |
159 pa = patch ("Faces", fvc.faces, "Vertices", fvc.vertices, | |
160 "FaceVertexCData", fvc.facevertexcdata, | |
161 "FaceColor", "flat", "EdgeColor", "none"); | |
162 else | |
163 pa = patch ("Faces", fvc.faces, "Vertices", fvc.vertices, | |
164 "FaceColor", "g", "EdgeColor", "k"); | |
165 endif | |
166 if (! ishold ()) | |
167 set (gca(), "view", [-37.5, 30], | |
168 "xgrid", "on", "ygrid", "on", "zgrid", "on"); | |
169 endif | |
170 case 1 | |
171 varargout = {fvc}; | |
172 case 2 | |
173 varargout = {fvc.faces, fvc.vertices}; | |
174 case 3 | |
175 varargout = {fvc.faces, fvc.vertices, fvc.facevertexcdata}; | |
176 otherwise | |
177 print_usage (); | |
178 endswitch | |
179 | |
180 endfunction | |
181 | |
182 | |
183 %!shared x, y, z, val | |
184 %! [x, y, z] = meshgrid (0:1, 0:1, 0:1); ## Points for single | |
185 %! val = [0, 0; 0, 0]; ## cube and a 3--dim | |
186 %! val(:,:,2) = [0, 0; 1, 0]; ## array of values | |
187 %!test | |
188 %! fv = isosurface (x, y, z, val, 0.3); | |
189 %! assert (isfield (fv, "vertices"), true); | |
190 %! assert (isfield (fv, "faces"), true); | |
191 %! assert (size (fv.vertices), [3 3]); | |
192 %! assert (size (fv.faces), [1 3]); | |
193 %!test | |
194 %! fvc = isosurface (x, y, z, val, .3, y); | |
195 %! assert (isfield (fvc, "vertices"), true); | |
196 %! assert (isfield (fvc, "faces"), true); | |
197 %! assert (isfield (fvc, "facevertexcdata"), true); | |
198 %! assert (size (fvc.vertices), [3 3]); | |
199 %! assert (size (fvc.faces), [1 3]); | |
200 %! assert (size (fvc.facevertexcdata), [3 1]); | |
201 %!test | |
202 %! [f, v] = isosurface (x, y, z, val, .3); | |
203 %! assert (size (f), [1 3]); | |
204 %! assert (size (v), [3 3]); | |
205 %!test | |
206 %! [f, v, c] = isosurface (x, y, z, val, .3, y); | |
207 %! assert (size (f), [1 3]); | |
208 %! assert (size (v), [3 3]); | |
209 %! assert (size (c), [3 1]); | |
210 | |
211 %!demo | |
212 %! clf | |
213 %! [x,y,z] = meshgrid(-2:0.5:2, -2:0.5:2, -2:0.5:2); | |
214 %! v = x.^2 + y.^2 + z.^2; | |
215 %! isosurface (x, y, z, v, 1) |