Code covered by the BSD License  

Highlights from
Isosurface Area Calculation

from Isosurface Area Calculation by Daniel Siderius
Computes the area of an isosurface (e.g., 3D contour) given three dimensional volume data.

isosurface_area(varargin)
function [fout, vout, cout] = isosurface_area(varargin)
%ISOSURFACE_AREA  Computes the area of an extracted Isosurface.
%  DEVELOPED FROM THE STOCK "ISOSURFACE.M" SCRIPT
%   FV = ISOSURFACE_AREA(X,Y,Z,V,ISOVALUE) computes isosurface area for
%   data V at isosurface value ISOVALUE. Arrays (X,Y,Z) specify the points
%   at which the data V is given. The struct FV contains the faces and
%   vertices of the isosurface and can be passed directly to the PATCH
%   command.
%   
%   FV = ISOSURFACE_AREA(V,ISOVALUE) assumes [X Y Z] = meshgrid(1:N, 1:M, 1:P) 
%        where [M,N,P]=SIZE(V). 
%   
%   FV = ISOSURFACE_AREA(X,Y,Z,V) or FV = ISOSURFACE_AREA(V) selects an
%   isosurface value automatically using the histogram of the
%   data. 
%   
%   FVC = ISOSURFACE_AREA(..., COLORS) interpolates the array COLORS onto
%   the scalar field and returns the interpolated values in
%   facevertexcdata. The size of the COLORS array must be the same
%   as V. 
%   
%   FV = ISOSURFACE_AREA(..., 'noshare') does not attempt to create
%   shared vertices. This is faster, but produces a larger set of
%   vertices.  
%   
%   FV = ISOSURFACE_AREA(..., 'verbose') prints progress messages to the
%        command window as the computation progresses. 
%   
%   [F, V] = ISOSURFACE_AREA(...) or  [F, V, C] = ISOSURFACE_AREA(...)
%   returns the faces and vertices (and facevertexcdata) in
%   separate arrays instead of a struct. 
%       
%
%   See also ISONORMALS, ISOCAPS, SMOOTH3, SUBVOLUME, REDUCEVOLUME,
%            REDUCEPATCH, SHRINKFACES.

%   Copyright 1984-2004 The MathWorks, Inc.
%   Developed from ISOSURFACE.m Revision: 1.8.4.5, Date: 2005/06/21 19:37:46
%   Area Calculator developed by Daniel W. Siderius (dwsideri@gmail.com)
%   $Revision: 1.0 $ $Date: 2009/09/25$


[x y z data colors value noshare verbose] = parseargs(nargin,varargin);

if length(value)>1
  error(id('ScalarIsovalue'),'Isovalue must be a scalar.'); 
end

% Take this out when other data types are handled
data = double(data);
colors = double(colors);

[msg x y z] = xyzvcheck(x,y,z,data);  error(msg) %#ok


if ~isempty(colors) && ~isequal(size(colors), size(data))
  error(id('ColorSizeMismatch'),'COLORS array must be the same size as V.'); 
end

if isempty(value)
  value = isovalue(data);
end

[v f c] = isosurf(data, colors, value, noshare, verbose);
v = v';  %these lines transpose the data
f = f';
c = c';
if isempty(v)
  v = [];
  f = [];
  c = [];
end

if ~isempty(x) && ~isempty(v)
  sz = size(x);
  if ~(isequal(x, 1:sz(2)) && isequal(y, 1:sz(1)) && isequal(z, 1:sz(3)))
    nv(:,1) = interp3( x,  v(:,1), v(:,2), v(:,3));
    nv(:,2) = interp3( y,  v(:,1), v(:,2), v(:,3));
    nv(:,3) = interp3( z,  v(:,1), v(:,2), v(:,3));
    v = nv;
  end
end

if nargout==0
  ax = [];
  fig = get(0, 'currentfigure'); 
  if ~isempty(fig)
    ax = get(fig, 'currentaxes');
  end

  p=patch('faces', f, 'vertices', v, 'facevertexcdata', value, ...
          'facecolor', 'flat', 'edgecolor', 'none', 'userdata', value);
      
  % Register handles with m-code generator
  mcoderegister('Handles',p,'Target',p,'Name','isosurface');        
 
  if ~isempty(c)
    set(p, 'facevertexcdata', c)
  end
  if ~isempty(x)
    isonormals(x,y,z,data, p);
  else
    isonormals(data, p);
  end
  
  if isempty(ax)
    view(3); 
    camlight; lighting gouraud
  end


%Begin the added source code - DWS 2009/09/25
  [ points numaxes ] = size(f);
%  points
  area = 0.0;
  for ID=1:points
    % For each triangle tile, use Heron's Formula to calculate its area, then add it to the accumulator
    a = sqrt( (v(f(ID,1),1)-v(f(ID,2),1))^2 + (v(f(ID,1),2)-v(f(ID,2),2))^2 + (v(f(ID,1),3)-v(f(ID,2),3))^2 );
    b = sqrt( (v(f(ID,2),1)-v(f(ID,3),1))^2 + (v(f(ID,2),2)-v(f(ID,3),2))^2 + (v(f(ID,2),3)-v(f(ID,3),3))^2 );
    c = sqrt( (v(f(ID,1),1)-v(f(ID,3),1))^2 + (v(f(ID,1),2)-v(f(ID,3),2))^2 + (v(f(ID,1),3)-v(f(ID,3),3))^2 );
    s = (a+b+c)/2.0;
    myarea = sqrt( s*(s-a)*(s-b)*(s-c) );
    area = area + myarea;
  end
  area

% Plot the vertex points if desired.
%  hold on
%  for ID=1:points
%    for j=1:3
%      plot3( v(f(ID,j),1),  v(f(ID,j),2), v(f(ID,j),3), '.')
%    end
%  end

elseif nargout == 1
  [ points numaxes ] = size(f);
  area = 0.0;
  for ID=1:points
    a = sqrt( (v(f(ID,1),1)-v(f(ID,2),1))^2 + (v(f(ID,1),2)-v(f(ID,2),2))^2 + (v(f(ID,1),3)-v(f(ID,2),3))^2 );
    b = sqrt( (v(f(ID,2),1)-v(f(ID,3),1))^2 + (v(f(ID,2),2)-v(f(ID,3),2))^2 + (v(f(ID,2),3)-v(f(ID,3),3))^2 );
    c = sqrt( (v(f(ID,1),1)-v(f(ID,3),1))^2 + (v(f(ID,1),2)-v(f(ID,3),2))^2 + (v(f(ID,1),3)-v(f(ID,3),3))^2 );
    s = (a+b+c)/2.0;
    myarea = sqrt( s*(s-a)*(s-b)*(s-c) );
    area = area + myarea;
  end

  fout = area;

else
  fout = f;
  vout = v;
  if ~isempty(c)
    cout = c;
  end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [x, y, z, data, colors, value, noshare, verbose] = parseargs(nin, vargin)


x = [];
y = [];
z = [];
colors = [];
value = [];
noshare = 0;
verbose = 0;

for j = 1:2
  if nin>0
    lastarg = vargin{nin};
    if ischar(lastarg)
      if ~isempty(lastarg)
	if lower(lastarg(1))=='n' % noshare
	  noshare = 1;
	end
	if lower(lastarg(1))=='v' % verbose
	  verbose = 1;
	end
      end
      nin = nin - 1;
    end
  end
end

if nin==1                % isosurface_area(v)
  data = vargin{1};
elseif nin==2            % isosurface_area(v, isoval), isosurface_area(v, colors) 
  data = vargin{1};
  value = vargin{2};
  if isequal(size(value), size(data))
    colors = value;
    value = [];
  end
elseif nin==3            % isosurface_area(v, isoval, colors) 
  data = vargin{1};
  value = vargin{2};
  colors = vargin{3};
elseif nin==4            % isosurface_area(x,y,z,v)
  x = vargin{1};
  y = vargin{2};
  z = vargin{3};
  data = vargin{4};
elseif nin==5            % isosurface_area(x,y,z,v, isovalue), isosurface_area(x,y,z,v, colors)
  x = vargin{1};
  y = vargin{2};
  z = vargin{3};
  data = vargin{4};
  value = vargin{5};
  if isequal(size(value), size(data))
    colors = value;
    value = [];
  end
elseif nin==6            % isosurface_area(x,y,z,v, isovalue, colors)
  x = vargin{1};
  y = vargin{2};
  z = vargin{3};
  data = vargin{4};
  value = vargin{5};
  colors = vargin{6};
else
  error(id('WrongNumberOfInputs'),'Wrong number of input arguments.'); 
end

function str=id(str)
str = ['MATLAB:isosurface_area:' str];

Contact us at files@mathworks.com