random.h 3.36 KB
``````#ifndef STIM_RANDOM
#define STIM_RANDOM

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stim/math/vec3.h>
#include <stim/math/constants.h>

namespace stim{

template<class T>
class Random{
protected:
void init() {
srand(time(NULL));
}

void init(unsigned int seed){
srand(seed);
}

public:
/// Default Constructor
Random(){
init();
}

/// Constructor from a seed.
/// A positive seed sets, 0 or negative yeilds the
Random(unsigned int seed){
init(seed);
}

///Returns a random number uniformly sampled between 0 and 1
static
T uniformRandom()
{
return (  (T)(rand()))/(  (T)(RAND_MAX));  ///generates a random number between 0 and 1 using the uniform distribution.
}

///Returns a random number from a normal distribution between 0 to 1.
static
T normalRandom()
{
T u1 = uniformRandom();
T u2 = uniformRandom();
return cos(2.0*atan(1.0)*u2)*sqrt(-1.0*log(u1));                                                             ///generate a random number using the normal distribution between      0 and 1.
}
///Return a random vec3 each value between 0 and 1 from a uniform distribution.
static
stim::vec3<T> uniformRandVector()
{
stim::vec3<T> r(uniformRandom(), uniformRandom(), 1.0);                                                  ///generate a random vector using the uniform distribution between 0 and 1.
return r;
}
///Return a random vec3, each value between 0 and 1 from a normal distribution.
static
stim::vec3<T> normalRandVector()
{
stim::vec3<float> r(normalRandom(), normalRandom(), 1.0);                                                    ///generate a random vector using the normal distribution between      0 and 1.
return r;
}

///place num_samples of samples on the surface of a sphere of radius r.
///returns an std::vector of vec3's in cartisian coordinates.
static std::vector<stim::vec3 <T> >
sample_sphere(unsigned int num_samples, T radius = 1, T solidAngle = stim::TAU)
{
std::cout << "did this" << std::endl;
T PHI[2], Z[2], range;      ///Range of angles in cylinderical coordinates
PHI[0] = solidAngle/2;          ///project the solid angle into spherical coords
PHI[1] = asin(0);               ///
Z[0] = cos(PHI[0]);             ///project the z into spherical coordinates
Z[1] = cos(PHI[1]);             ///
range = Z[0] - Z[1];            ///the range of all possible z values.

T z, theta, phi;            /// temporary individual

std::vector<stim::vec3<T> > samples;

//srand(100);                     ///set random seed

for(int i = 0; i < num_samples; i++)		///for each sample
{
z = uniformRandom()*range + Z[1];	///find a random z based on the solid angle
theta = uniformRandom() * stim::TAU;	///find theta
phi = acos(z);				///project into spherical coord phi
stim::vec3<T> sph(radius, theta, phi);	///assume spherical
stim::vec3<T> cart = sph.sph2cart();	///conver to cartesisn
samples.push_back(cart);		///push into list
}

///THIS IS DEBUGGING CODE, UNCOMMENT TO CHECK WHETHER THE SURFACE IS WELL SAMPLED!
/*
std::stringstream name;
for(int i = 0; i < num_samples; i++)
name << samples[i].str() << std::endl;

std::ofstream outFile;
outFile.open("Sampled Surface.txt");
outFile << name.str().c_str();
*/

return samples;					///return full list.
}
};

}

#endif
``````