source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp @ 2873

Revision 2873, 2.2 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "common.h"
2#include "SampleGenerator.h"
3#include "Halton.h"
4
5using namespace std;
6
7//SampleGenerator::SampleGenerator() {}
8
9SampleGenerator::SampleGenerator(int numSamples, float radius):
10mNumSamples(numSamples), mRadius(radius)
11{}
12
13
14PoissonDiscSampleGenerator::PoissonDiscSampleGenerator(int numSamples, float radius):
15SampleGenerator(numSamples, radius)
16{}
17
18
19void PoissonDiscSampleGenerator::Generate(Sample2 *samples) const
20{
21        // this is a hacky poisson sampling generator which does random dart-throwing
22        // until it is not able to place any dart for a number of tries
23        // in this case, the required min distance is reduced
24        // the solution is a possion sampling with respect to the adjusted min distance
25        // better solutions have been proposed, i.e., using hierarchical sampling
26
27        const float maxTries = 1000;
28        const float f_reduction = 0.9f;
29
30        static HaltonSequence halton;
31        float r[2];
32
33        // generates poisson distribution on disc
34        float minDist = 2.0f / sqrt((float)mNumSamples);
35
36        //cout << "minDist before= " << minDist << endl;
37
38        for (int i = 0; i < mNumSamples; ++ i)
39        {
40                int tries = 0, totalTries = 0;
41
42                // repeat until valid sample was found
43                while (1)
44                {
45                        ++ tries;
46                        ++ totalTries;
47
48                        halton.GetNext(2, r);
49
50                        const float rx = r[0] * 2.0f - 1.0f;
51                        const float ry = r[1] * 2.0f - 1.0f;
52
53                        // check if in disk, else exit early
54                        if (rx * rx + ry * ry > 1)
55                                continue;
56
57                        bool sampleValid = true;
58
59                        // check poisson property
60                        for (int j = 0; ((j < i) && sampleValid); ++ j)
61                        {
62                                const float dist =
63                                        sqrt((samples[j].x - rx) * (samples[j].x - rx) +
64                                             (samples[j].y - ry) * (samples[j].y - ry));
65                       
66                                if (dist < minDist)
67                                        sampleValid = false;
68                        }
69
70                        if (sampleValid)
71                        {
72                                samples[i].x = rx;
73                                samples[i].y = ry;
74                                break;
75                        }
76
77                        if (tries > maxTries)
78                        {
79                                minDist *= f_reduction;
80                                tries = 0;
81                        }
82                }
83               
84                //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;
85        }
86
87        //cout << "minDist after= " << minDist << endl;
88}
Note: See TracBrowser for help on using the repository browser.