/* License: GPL v2 or later */ // I wrote this in C because the Haskell version I had wasn't being fast // enough for me. Now this is simple and works great! #include #include #include #include #include #include "foreignPollution.h" void foreignPollution(uint32_t randSeed, const double * pollution, uint32_t pollutionWidth, uint32_t pollutionHeight) { uint32_t x, y; const uint32_t negative1AsXYtype = -1; #define AT(array,x,y) ( (array)[((x)*(array##Height))+((y))] ) //Glibc's parameters, seems to work fine. See wikipedia //http://en.wikipedia.org/wiki/Linear_congruential_generator #define RAND() ( randSeed = (((randSeed * 1103515245u) + 12345u) & 0x7fffffffu) ) #define RAND_FLOAT_UP_TO(hi) ( (double)RAND() * (hi) / 0x7fffffffu ) #define RAND_FLOAT_BETWEEN(lo,hi) ( (lo) + (double)RAND() * ((hi)-(lo)) / 0x7fffffffu ) glPushMatrix(); // To log pollution amounts to stderr (enable by changing the 'if'). if(0) { for(y = pollutionHeight-1; y != negative1AsXYtype; --y) { for(x = 0; x != pollutionWidth; ++x) { const int roundedPollution = AT(pollution,x,y); const char indicator = ( (roundedPollution < 10) ? ( '0' + roundedPollution ) : ( 'a' + (roundedPollution-10) )); fputc(indicator, stderr); } printf("\n"); } printf("\n"); } glScaled(1.0/3.0, 1.0/3.0, 1); glTranslated(-0.5, -0.5, 0.0); glBegin(GL_QUADS); const uint32_t deterministicHeavinessWidth = pollutionWidth + 2; const uint32_t deterministicHeavinessHeight = pollutionHeight + 2; double * deterministicHeaviness = (double*)alloca(deterministicHeavinessWidth*deterministicHeavinessHeight*sizeof(double)); const uint32_t minX = 0; const uint32_t minY = 0; const uint32_t maxX = deterministicHeavinessWidth - 1; const uint32_t maxY = deterministicHeavinessHeight - 1; for(x = 0; x != deterministicHeavinessWidth; ++x) for(y = 0; y != deterministicHeavinessHeight; ++y) { //should probably move in 1 to find border pollution amounts //...but NOT segfault :-) const int is_border = (x == minX || y == minY || x == maxX || y == maxY); const double pollution_here = (is_border ? 0.0 : AT(pollution,x-1,y-1)); //Maybe logarithm-of-pollution? (log ( 1 + pollution_here)) AT(deterministicHeaviness,x,y) = pollution_here; } const uint32_t drawnWidth = pollutionWidth * 3 + 1; const uint32_t drawnHeight = pollutionHeight * 3 + 1; for(x = 0; x != drawnWidth; ++x) for(y = 0; y != drawnHeight; ++y) { const double heaviness1 = AT(deterministicHeaviness,(x+2)/3,(y+2)/3); const double heaviness2 = AT(deterministicHeaviness,(x+3)/3,(y+2)/3); const double heaviness3 = AT(deterministicHeaviness,(x+3)/3,(y+3)/3); const double heaviness4 = AT(deterministicHeaviness,(x+2)/3,(y+3)/3); // if(heaviness1 > 1 || heaviness2 > 1 || heaviness3 > 1 || heaviness4 > 1) { glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(heaviness1)); glVertex2i(x , y ); glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(heaviness2)); glVertex2i(x+1, y ); glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(heaviness3)); glVertex2i(x+1, y+1); glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(heaviness4)); glVertex2i(x , y+1); // } /*glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(AT(deterministicHeaviness,(x+2)/3,(y+2)/3))); glVertex2i(x , y ); glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(AT(deterministicHeaviness,(x+3)/3,(y+2)/3))); glVertex2i(x+1, y ); glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(AT(deterministicHeaviness,(x+3)/3,(y+3)/3))); glVertex2i(x+1, y+1); glColor4d(0.5, 0.5, 0.5, RAND_FLOAT_UP_TO(AT(deterministicHeaviness,(x+2)/3,(y+3)/3))); glVertex2i(x , y+1);*/ } glEnd(); glPopMatrix(); }