00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "sampling.h"
00026
00027 #define SQRT_SAMPLE_TABLE_SIZE 64
00028 #define SAMPLE_TABLE_SIZE (SQRT_SAMPLE_TABLE_SIZE * \
00029 SQRT_SAMPLE_TABLE_SIZE)
00030
00031 int line_num = 0;
00032 string current_file;
00033
00034 static float imageSamples[SAMPLE_TABLE_SIZE][2];
00035 static float timeSamples[SAMPLE_TABLE_SIZE];
00036 static float lensSamples[SAMPLE_TABLE_SIZE][2];
00037
00038 static void addSampleToGrid(float sample[][2],
00039 int sampleNum, SampleGrid *grid) {
00040 int u = GRID(sample[sampleNum][0]);
00041 int v = GRID(sample[sampleNum][1]);
00042 (*grid)[u][v].push_back(sampleNum);
00043 }
00044 inline float Wrapped1DDist(float a, float b) {
00045 float d = fabsf(a - b);
00046 if (d < 0.5f) return d;
00047 else return 1.f - max(a, b) + min(a, b);
00048 }
00049
00050 void BestCandidate2D(float table[][2],
00051 int count, SampleGrid *grid = NULL);
00052 static void
00053 Redistribute2D(float samples[][2], SampleGrid &pixelGrid);
00054 int main() {
00055
00056 SampleGrid pixelGrid;
00057 BestCandidate2D(imageSamples,
00058 SAMPLE_TABLE_SIZE, &pixelGrid);
00059
00060 ProgressReporter timeProgress(SAMPLE_TABLE_SIZE, "Time samples");
00061 for (int i = 0; i < SAMPLE_TABLE_SIZE; ++i)
00062 timeSamples[i] = (i + lux::random::floatValue()) /
00063 SAMPLE_TABLE_SIZE;
00064 for (int currentSample = 1;
00065 currentSample < SAMPLE_TABLE_SIZE;
00066 ++currentSample) {
00067
00068 int best = -1;
00069
00070 float maxMinDelta = 0.;
00071 for (int t = currentSample; t < SAMPLE_TABLE_SIZE; ++t) {
00072
00073 int gu = GRID(imageSamples[currentSample][0]);
00074 int gv = GRID(imageSamples[currentSample][1]);
00075 float minDelta = INFINITY;
00076 for (int du = -1; du <= 1; ++du) {
00077 for (int dv = -1; dv <= 1; ++dv) {
00078
00079
00080 int u = gu + du, v = gv + dv;
00081 if (u < 0) u += BC_GRID_SIZE;
00082 if (u >= BC_GRID_SIZE) u -= BC_GRID_SIZE;
00083 if (v < 0) v += BC_GRID_SIZE;
00084 if (v >= BC_GRID_SIZE) v -= BC_GRID_SIZE;
00085 for (u_int g = 0; g < pixelGrid[u][v].size(); ++g) {
00086 int otherSample = pixelGrid[u][v][g];
00087 if (otherSample < currentSample) {
00088 float dt = Wrapped1DDist(timeSamples[otherSample],
00089 timeSamples[t]);
00090 minDelta = min(minDelta, dt);
00091 }
00092 }
00093 }
00094 }
00095
00096 if (minDelta > maxMinDelta) {
00097 maxMinDelta = minDelta;
00098 best = t;
00099 }
00100 }
00101 BOOST_ASSERT(best != -1);
00102 swap(timeSamples[best], timeSamples[currentSample]);
00103 timeProgress.Update();
00104 }
00105 timeProgress.Done();;
00106
00107 BestCandidate2D(lensSamples, SAMPLE_TABLE_SIZE);
00108 Redistribute2D(lensSamples, pixelGrid);
00109
00110 FILE *f = fopen("sampledata.cpp", "w");
00111 if (f == NULL) {
00112 Severe("Couldn't open sampledata.cpp for writing.");
00113 }
00114 fprintf(f, "\n/* Automatically generated %dx%d sample "
00115 "table (%s @ %s) */\n\n",
00116 SQRT_SAMPLE_TABLE_SIZE, SQRT_SAMPLE_TABLE_SIZE,
00117 __DATE__, __TIME__);
00118 fprintf(f, "const float "
00119 "BestCandidateSampler::sampleTable[%d][5] = {\n",
00120 SAMPLE_TABLE_SIZE);
00121 for (int i = 0; i < SAMPLE_TABLE_SIZE; ++i) {
00122 fprintf(f, " { ");
00123 fprintf(f, "%10.10ff, %10.10ff, ", imageSamples[i][0],
00124 imageSamples[i][1]);
00125 fprintf(f, "%10.10ff, ", timeSamples[i]);
00126 fprintf(f, "%10.10ff, %10.10ff, ", lensSamples[i][0],
00127 lensSamples[i][1]);
00128 fprintf(f, "},\n");
00129 }
00130 fprintf(f, "};\n");
00131 return 0;
00132 }
00133 void BestCandidate2D(float table[][2], int totalSamples,
00134 SampleGrid *grid) {
00135 SampleGrid localGrid;
00136 if (!grid) grid = &localGrid;
00137 ProgressReporter
00138 progress(totalSamples-1, "Throwing Darts");
00139
00140 table[0][0] = lux::random::floatValue();
00141 table[0][1] = lux::random::floatValue();
00142 addSampleToGrid(table, 0, grid);
00143 for (int currentSample = 1;
00144 currentSample < totalSamples;
00145 ++currentSample) {
00146
00147 float maxDist2 = 0.;
00148 int numCandidates = 500 * currentSample;
00149 for (int currentCandidate = 0;
00150 currentCandidate < numCandidates;
00151 ++currentCandidate) {
00152
00153 float candidate[2];
00154 candidate[0] = lux::random::floatValue();
00155 candidate[1] = lux::random::floatValue();
00156
00157 float sampleDist2 = INFINITY;
00158 int gu = GRID(candidate[0]), gv = GRID(candidate[1]);
00159 for (int du = -1; du <= 1; ++du) {
00160 for (int dv = -1; dv <= 1; ++dv) {
00161
00162 int u = gu + du, v = gv + dv;
00163 if (u < 0) u += BC_GRID_SIZE;
00164 if (u >= BC_GRID_SIZE) u -= BC_GRID_SIZE;
00165 if (v < 0) v += BC_GRID_SIZE;
00166 if (v >= BC_GRID_SIZE) v -= BC_GRID_SIZE;
00167
00168 for (u_int g = 0; g < (*grid)[u][v].size(); ++g) {
00169 int s = (*grid)[u][v][g];
00170 float xdist = Wrapped1DDist(candidate[0], table[s][0]);
00171 float ydist = Wrapped1DDist(candidate[1], table[s][1]);
00172 float d2 = xdist*xdist + ydist*ydist;
00173 sampleDist2 = min(sampleDist2, d2);
00174 }
00175 }
00176 }
00177
00178 if (sampleDist2 > maxDist2) {
00179 maxDist2 = sampleDist2;
00180 table[currentSample][0] = candidate[0];
00181 table[currentSample][1] = candidate[1];
00182 }
00183 }
00184 addSampleToGrid(table, currentSample, grid);
00185 progress.Update();
00186 }
00187 progress.Done();
00188 }
00189 static void Redistribute2D(float samples[][2],
00190 SampleGrid &pixelGrid) {
00191 ProgressReporter progress(SAMPLE_TABLE_SIZE, "Redistribution");
00192 for (int currentSample = 1;
00193 currentSample < SAMPLE_TABLE_SIZE; ++currentSample) {
00194
00195 int best = -1;
00196
00197 float maxMinDist2 = 0.f;
00198 for (int samp = currentSample; samp < SAMPLE_TABLE_SIZE;
00199 ++samp) {
00200
00201 int gu = GRID(imageSamples[currentSample][0]);
00202 int gv = GRID(imageSamples[currentSample][1]);
00203 float minDist2 = INFINITY;
00204 for (int du = -1; du <= 1; ++du) {
00205 for (int dv = -1; dv <= 1; ++dv) {
00206
00207
00208 int u = gu + du, v = gv + dv;
00209 if (u < 0) u += BC_GRID_SIZE;
00210 if (u >= BC_GRID_SIZE) u -= BC_GRID_SIZE;
00211 if (v < 0) v += BC_GRID_SIZE;
00212 if (v >= BC_GRID_SIZE) v -= BC_GRID_SIZE;
00213 for (u_int g = 0; g < pixelGrid[u][v].size(); ++g) {
00214 int s2 = pixelGrid[u][v][g];
00215 if (s2 < currentSample) {
00216 float dx = Wrapped1DDist(samples[s2][0],
00217 samples[samp][0]);
00218 float dy = Wrapped1DDist(samples[s2][1],
00219 samples[samp][1]);
00220 float d2 = dx*dx + dy*dy;
00221 minDist2 = min(d2, minDist2);
00222 }
00223 }
00224 }
00225 }
00226
00227 if (minDist2 > maxMinDist2) {
00228 maxMinDist2 = minDist2;
00229 best = samp;
00230 }
00231 }
00232 BOOST_ASSERT(best != -1);
00233 swap(samples[best][0], samples[currentSample][0]);
00234 swap(samples[best][1], samples[currentSample][1]);
00235 progress.Update();
00236 }
00237 fprintf(stderr, "\n");
00238 progress.Done();
00239 }