function FISH = spherefish(n, R, md)


% H = spherefish(n, R, md) - Random points in a spheric volume
%
% The SPHEREFISH() function works similar to randfish(), and has the
% same output, but it generates points inside a spherical volume of
% radius R. The number of fish generated is n, and md is the minimum
% starting distance (center to center) between the fish (this should 
% be no less than 1 BL, or fish might start out on top of each other).
% Note that the function does not actually generate numbers inside a
% spherical volume, but rather, inside of a cubic volume that circumscribes
% the sphere, and then tosses out any outside the sphere and re-generates,
% until it has n points inside the cube, and also inside the sphere,
% all of which are > md from one another in 3D.
% 

%Created by Jim Work, University of South Carolina, August 13th, 2003


% Input parameters are:
% n = Number of fish
% R = radius of the spherical volume in which the fish start (cm)
% md = minimum distance between fish centroids (cm)
% 
% A 12-column matrix is returned, with one row per fish. The columns
% contain:
% - the frame number (col. 1)
% - the individual number (col. 2)
% - position in x-y-z (col. 3-5)
% - velocity in cm/frame (col. 6-8)
% - Force in dynes (col. 9-11)
% - flag on whether it is an observed or inferred point (0 for models).
%
% Example:
% F = spherefish(4,60,2)
% 
% F =
% 
%   Columns 1 through 7 
% 
%          0    1.0000   19.3743  -49.6504  -26.6437    0.1254    0.4208
%          0    2.0000    1.1361   -6.7531  -48.1014   -0.6193    0.5305
%          0    3.0000  -37.8746   10.4168    6.8734    0.1327    0.4769
%          0    4.0000   33.1907  -47.0825  -10.3573   -0.4138    0.7151
% 
%   Columns 8 through 12 
% 
%    -0.7371    0.1254    0.4208   -0.7371         0
%     0.0786   -0.6193    0.5305    0.0786         0
%     0.6756    0.1327    0.4769    0.6756         0
%    -0.1033   -0.4138    0.7151   -0.1033         0


% First, generate the time = 0 column vector:
TIME = zeros(n,1);

% Next, we generate a matrix n x n wide, and fill it with numbers
% astronomically large. These will then be replaced with actual
% distances.

DIST = 9999 * ones(n, n);

% Next, we generate an array, 4 columns long, of individual %'s and
% their X- and Y- coordinates. Again, we do this by starting with 
% all zeros.

% Set up the random number seed so that we have true, rather than pseudo, random
% numbers (note that if you don't do this, the random numbers start off the same
% every time you restart MatLab). We use clock as the variable, since the system 
% clock will be different every time this function is called.

rand('state',sum(100*clock));		


PTS = zeros(n, 4);

% Now, we generate random points, and check them to make sure
% the minimum distance between pts is at least 'md' units

for i = 1:n            % loop over all members of the group
    
    mindist = 0;
    
    % keep generating randing numbers until you the minimum NND
    % is > md.
    
    while (mindist <= md)  
        
        % Start by generating points randomly inside of a cubic
        % volume (this is the easiest way to generate a coordinate
        % triplet).
        
        X = R * (2 * rand - 1);        % generate an X value from 0 to L 
        Y = R * (2 * rand - 1);        % generate a Y value from 0 to  W 
        Z = R * (2 * rand - 1);        % generate a Z value from 0 to H 
        
        % Now we check to make sure that the point is inside the
        % spherical volume (that is, it is <= R radius away from
        % the center point, (0,0,0). If it is not, we throw it out
        % and re-generate the points.
        
        d2c = dist3d(0,0,0,X,Y,Z);
        
        while ( d2c > R )
            % It's inside the cube but outside the sphere
            % circumscribed byt the cube. Thus we must regenerate
            % the points.
            
            X = R * (2 * rand - 1);        % generate an X value from 0 to L 
            Y = R * (2 * rand - 1);        % generate a Y value from 0 to  W 
            Z = R * (2 * rand - 1);        % generate a Z value from 0 to H 
            
            % Check again to make sure it's inside the sphere as well
            % as the cube.
            d2c = dist3d(0,0,0,X,Y,Z);
        end
        
        for j = 1:i-1        % loop over all the previously-generated guys
            DIST(i,j) = dist3d(X,  Y,  Z, PTS(j,2),PTS(j,3), PTS(j,4));
        end
        
        mindist = min(DIST(i,:));
        
    end					    % end k loop    
    
    % Now we've found a point that's not too close. We can
    % add it to the PTS matrix
    
    PTS(i,1) = round(i);    % assign the index number to individual i
    PTS(i,2) = X;           % assign X as the x-coord of individual i
    PTS(i,3) = Y;           % assign Y as the y-coord of individual i
    PTS(i,4) = Z;           % assign Z as the z-coord of individual i
    
end	                    % terminate i loop

% Now we build the matrix for velocity. At the start, mean velocity 
% is between 0 and 1. Since each time step is equivalent to one 'frame' 
% of video, and we capture and film at 30 Hz (frames/sec), a velocity of
% 1 cm/step = 1 cm/frame = 30 cm/s, so that it could cross the tank in 
% 3.3 seconds. Any faster than that would probably cause the model fish 
% to swim THROUGH the walls if things were set up wrong. Since fish can 
% swim in either direction, this number should be between -1 and 1, actually.

VEL = (2 * rand(n,3)) - 1;

% Compute force, assuming t = 1. Since a = v / t, if t = 1, then a = v. 
% Since F = m * a, and a = v, F = m * v. If we assume m = 1g for the
% fish, then (at least to start with), F = v. That is, the Force vectors
% basically start the fish off with the same magnitude as the velocity
% vectors and in the same direction.

FORCE = VEL;  

% And finally, the FLAG matrix, which is all 0's because it's known data
% and not interpolated.
FLAG = zeros(n,1);

% concatenate all the pertinent matrices into one big giant one for output:
FISH = [ TIME PTS VEL FORCE FLAG];
