Advertisement
Guest User

multiscale turing pattern

a guest
Jan 10th, 2012
673
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.72 KB | None | 0 0
  1. #include "testApp.h"
  2.  
  3. typedef vector<float> floats;
  4. typedef vector<unsigned char> bytes;
  5. typedef vector<bool> bools;
  6.  
  7. int n, side, levels;
  8. floats grid;
  9. floats diffusionLeft, diffusionRight, variation;
  10. floats bestVariation;
  11. bytes bestLevel;
  12. bools direction;
  13.  
  14. vector<float> stepSizes;
  15. vector<int> radii;
  16. ofImage buffer;
  17.  
  18. void testApp::setup() {
  19.     // initialize settings
  20.     side = 512;
  21.     float base = ofRandom(1.5, 2.5);
  22.     levels = logf(side) / logf(base);
  23.     float stepScale = ofRandom(-.003, +.003) + .009;
  24.     float stepOffset = ofRandom(-.003, +.003) + .008;
  25.    
  26.     // allocate space
  27.     n = side * side;
  28.     radii.resize(levels);
  29.     stepSizes.resize(levels);
  30.     grid.resize(n);
  31.     diffusionLeft.resize(n);
  32.     diffusionRight.resize(n);
  33.     variation.resize(n);
  34.     bestVariation.resize(n);
  35.     bestLevel.resize(n);
  36.     direction.resize(n);
  37.     buffer.allocate(side, side, OF_IMAGE_GRAYSCALE);
  38.    
  39.     // determines the shape of the patterns
  40.     for(int i = 0; i < levels; i++) {
  41.         int radius = (int) powf(base, i);
  42.         radii[i] = radius;
  43.         float diameterRatio = (float) ((2 * radius) + 1) / side;
  44.         cout << i << ":" << (int) (100 * diameterRatio) << "%" << endl;
  45.         stepSizes[i] = log(radius) * stepScale + stepOffset;
  46.     }
  47.  
  48.     // initialize the grid with noise
  49.   for (int i = 0; i < n; i++) {
  50.         grid[i] = ofRandom(-1, +1);
  51.   }
  52.     // initialize with a few pixels
  53.     for(int i = 0; i < 8; i++) {
  54.         grid[ofRandom(0, side) * side + ofRandom(0, side)] = ofRandom(-.01, +.01);
  55.     }
  56. }
  57.  
  58. void testApp::update() {
  59.     floats* activator = &grid;
  60.     floats* inhibitor = &diffusionRight;
  61.    
  62.     Mat variationMat(side, side, CV_32FC1, &(variation[0]));
  63.    
  64.     for(int level = 0; level < levels - 1; level++) {
  65.         Mat activatorMat(side, side, CV_32FC1, &((*activator)[0]));
  66.         Mat inhibitorMat(side, side, CV_32FC1, &((*inhibitor)[0]));
  67.        
  68.         // blur activator into inhibitor
  69.         int radius = radii[level];
  70.         cv::Size kernelSize(radius * 2 + 1, radius * 2 + 1);
  71.         cv::blur(activatorMat, inhibitorMat, kernelSize);
  72.         //cv::GaussianBlur(activatorMat, inhibitorMat, kernelSize, 0);
  73.        
  74.         // absdiff between activator and inhibitor
  75.         cv::absdiff(activatorMat, inhibitorMat, variationMat);
  76.        
  77.         if(level == 0) {
  78.             // save bestLevel and bestVariation
  79.             for(int i = 0; i < n; i++) {
  80.                 bestVariation[i] = variation[i];
  81.                 bestLevel[i] = level;
  82.                 direction[i] = (*activator)[i] > (*inhibitor)[i];
  83.             }
  84.             activator = &diffusionRight;
  85.             inhibitor = &diffusionLeft;
  86.         } else {
  87.             // check/save bestLevel and bestVariation
  88.             for(int i = 0; i < n; i++) {
  89.                 if(variation[i] < bestVariation[i]) {
  90.                     bestVariation[i] = variation[i];
  91.                     bestLevel[i] = level;
  92.                     direction[i] = (*activator)[i] > (*inhibitor)[i];
  93.                 }
  94.             }
  95.             swap(activator, inhibitor);
  96.         }
  97.     }
  98.    
  99.     // update grid from bestLevel
  100.     float smallest = 10;
  101.     float largest = -10;
  102.     for(int i = 0; i < n; i++) {
  103.         float curStep = stepSizes[bestLevel[i]];
  104.         if(direction[i]) {
  105.             grid[i] += curStep;
  106.         } else {
  107.             grid[i] -= curStep;
  108.         }
  109.         smallest = min(smallest, grid[i]);
  110.         largest = max(largest, grid[i]);
  111.     }
  112.    
  113.     // normalize to [-1, +1]
  114.     float range = (largest - smallest) / 2;
  115.     for (int i = 0; i < n; i++) {
  116.         grid[i] = ((grid[i] - smallest) / range) - 1;
  117.     }
  118. }
  119.  
  120. template <class T>
  121. void drawBuffer(vector<T>& grid) {
  122.     unsigned char* pixels = buffer.getPixels();
  123.   for (int i = 0; i < n; i++) {
  124.         pixels[i] = 128 + 128 * grid[i];
  125.   }
  126.     buffer.update();
  127.     buffer.draw(0, 0);//, ofGetWidth(), ofGetHeight());
  128. }
  129.  
  130. void testApp::draw() {
  131.     drawBuffer(grid);
  132.     ofDrawBitmapString(ofToString((int) ofGetFrameRate()), 10, 20);
  133. }
  134.  
  135. void testApp::mousePressed(int x, int y, int button) {
  136.     setup();
  137. }
  138.  
  139. void testApp::keyPressed(int key) {
  140.     if(key == ' ') {
  141.         buffer.saveImage(ofToString(ofGetFrameNum()) + ".png");
  142.     }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement