Home > bioelectromagnetism > elec_fit_sphere.m

elec_fit_sphere

PURPOSE ^

elec_fit_sphere - find radius of sphere and closest spherical points to XYZ

SYNOPSIS ^

function [r,x,y,z] = elec_fit_sphere(X,Y,Z,xo,yo,zo,estim)

DESCRIPTION ^

 elec_fit_sphere - find radius of sphere and closest spherical points to XYZ

 Usage: [r,x,y,z] = elec_fit_sphere(X,Y,Z,xo,yo,zo)

 Notes:    The general formula for a sphere, with radius r is given by:

           (x - xo)^2  +  (y - yo)^2  +  (z - zo)^2  =  r^2

           This function takes arguments for cartesian co-ordinates
           of X,Y,Z (assume Z > 0) and the center of the sphere (xo,yo,zo).
           If (xo,yo,zo) are not provided, they are assumed (0,0,0).

           Returns values are the radius 'r' and the (x,y,z) Cartesian
           co-ordinates for the fitted sphere.

           See also, elec_sphere_project.m

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [r,x,y,z] = elec_fit_sphere(X,Y,Z,xo,yo,zo,estim)
0002 
0003 % elec_fit_sphere - find radius of sphere and closest spherical points to XYZ
0004 %
0005 % Usage: [r,x,y,z] = elec_fit_sphere(X,Y,Z,xo,yo,zo)
0006 %
0007 % Notes:    The general formula for a sphere, with radius r is given by:
0008 %
0009 %           (x - xo)^2  +  (y - yo)^2  +  (z - zo)^2  =  r^2
0010 %
0011 %           This function takes arguments for cartesian co-ordinates
0012 %           of X,Y,Z (assume Z > 0) and the center of the sphere (xo,yo,zo).
0013 %           If (xo,yo,zo) are not provided, they are assumed (0,0,0).
0014 %
0015 %           Returns values are the radius 'r' and the (x,y,z) Cartesian
0016 %           co-ordinates for the fitted sphere.
0017 %
0018 %           See also, elec_sphere_project.m
0019 %
0020 
0021 % $Revision: 1.2 $ $Date: 2005/07/12 21:26:24 $
0022 
0023 % Licence:  GNU GPL, no implied or express warranties
0024 % History:  06/01   Darren.Weber_at_radiology.ucsf.edu
0025 %
0026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0027 
0028 % initialise centroid, unless input parameters defined
0029 if ~exist('xo','var') xo = 0; else, if isempty(xo) xo = 0; end, end
0030 if ~exist('yo','var') yo = 0; else, if isempty(yo) yo = 0; end, end
0031 if ~exist('zo','var') zo = 0; else, if isempty(zo) zo = 0; end, end
0032 
0033 % The data is assumed a rough hemisphere.
0034 % To fit to a sphere, we duplicate first, with negative Z.
0035 
0036 Zmin = min(Z); Z = Z + ( 0 - Zmin ); % translate Z so min(Z) = zero
0037 % also used below to recalc Z
0038 X2 = [X;X];
0039 Y2 = [Y;Y];
0040 Z2 = [Z;-Z];
0041 
0042 % Initialise r0 as a rough guess at the sphere radius
0043 rX = (max(X2) - min(X2)) / 2;
0044 rY = (max(Y2) - min(Y2)) / 2;
0045 rZ = (max(Z2) - min(Z2)) / 2;
0046 r0 = mean([ rX rY rZ ]);
0047 
0048 if ~exist('estim','var') estim = 1; 
0049 else, if isempty(estim) estim = 1; end, end
0050 
0051 if estim ==1, 
0052   fprintf('\n%s%f\n', 'Initial spherical radius   = ', r0); end
0053 
0054 % perform least squares estimate of spherical radius (r)
0055 options = optimset('fminsearch');
0056 [r,fval,exitflag,output] = fminsearch('elec_fit_sphere_optim',...
0057   r0, options, X2, Y2, Z2, xo, yo, zo);
0058 %fprintf('\n%s%f\n', 'Iterations = ', output.iterations);
0059 %fprintf('\n%s%d\n', 'Exit = ', exitflag);
0060 
0061 if estim ==1,
0062   fprintf('%s%f\n',   'Estimated spherical radius = ', r); end
0063 
0064 
0065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0066 %   Fit all X,Y,Z to sphere
0067 %
0068 %   It'd be better to find the intersection of the line from (xo,yo,zo)
0069 %   to (x,y,z) intersecting the sphere:
0070 %
0071 %   (sX,sY,sZ) where s = 1 / (X/r)^2 + (Y/r)^2 + (Z/r)^2
0072 %
0073 %   Instead, this routine generates points on the sphere
0074 %   and then locates the closest of these to each (x,y,z).
0075 
0076 [Xs,Ys,Zs] = elec_sphere_points(40,80,r);
0077 
0078 % For each given X,Y,Z point, locate the nearest Xs,Ys,Zs.
0079 
0080 x = zeros(size(X)); y = zeros(size(Y)); z = zeros(size(Z));
0081 
0082 for s = 1:length(X)
0083   
0084   xs = X(s);  ys = Y(s);  zs = Z(s);  % Get original values
0085   
0086   % Generate matrix of linear distances between point (X,Y,Z)
0087   % and all points on the sphere (Xs,Ys,Zs).  Could be arc
0088   % length, but doesn't matter here.
0089   d = sqrt( (Xs-xs).^2 + (Ys-ys).^2 + (Zs-zs).^2 );
0090   m = min(min(d));
0091   
0092   index = find (d <= m); i = index(1);
0093   
0094   if isfinite(Xs(i)) x(s) = Xs(i); 
0095   else fprintf('\n\aWarning: Xs(i) is NaN: %d', Xs(i)); end
0096   if isfinite(Ys(i)) y(s) = Ys(i); 
0097   else fprintf('\n\aWarning: Ys(i) is NaN: %d', Ys(i)); end
0098   if isfinite(Zs(i)) z(s) = Zs(i); 
0099   else fprintf('\n\aWarning: Zs(i) is NaN: %d', Zs(i)); end
0100   
0101 end
0102 z = z + Zmin;    % restore z to original height
0103 Zs = Zs + Zmin;

Generated on Mon 15-Aug-2005 15:36:19 by m2html © 2003