#include "common.h" #include "SampleGenerator.h" #include "Halton.h" using namespace std; //SampleGenerator::SampleGenerator() {} SampleGenerator::SampleGenerator(int numSamples, float radius): mNumSamples(numSamples), mRadius(radius) {} PoissonDiscSampleGenerator::PoissonDiscSampleGenerator(int numSamples, float radius): SampleGenerator(numSamples, radius) {} void PoissonDiscSampleGenerator::Generate(Sample2 *samples) const { static HaltonSequence halton; float r[2]; // generates poisson distribution on disc float minDist = 2.0f / sqrt((float)mNumSamples); //cout << "minDist before= " << minDist << endl; for (int i = 0; i < mNumSamples; ++ i) { int tries = 0, totalTries = 0; // repeat until valid sample was found while (1) { ++ tries; ++ totalTries; halton.GetNext(2, r); const float rx = r[0] * 2.0f - 1.0f; const float ry = r[1] * 2.0f - 1.0f; // check if in disk, else exit early if (rx * rx + ry * ry > 1) continue; bool sampleValid = true; // check poisson property for (int j = 0; ((j < i) && sampleValid); ++ j) { const float dist = sqrt((samples[j].x - rx) * (samples[j].x - rx) + (samples[j].y - ry) * (samples[j].y - ry)); if (dist < minDist) sampleValid = false; } if (sampleValid) { samples[i].x = rx; samples[i].y = ry; break; } if (tries > 2000) { minDist *= 0.9f; tries = 0; } } //cout << "sample: " << samples[i].x << " " << i << " " << samples[i].y << " r: " << sqrt(samples[i].x * samples[i].x + samples[i].y * samples[i].y) << " tries: " << totalTries << endl; } //cout << "minDist after= " << minDist << endl; }