Advertisement
Guest User

DIAMOND SQUARE WORLD

a guest
Jul 23rd, 2014
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.87 KB | None | 0 0
  1. import java.util.Random;
  2.  
  3. double[][] data;
  4. int ds = 257;
  5.  
  6. void setup() {
  7.     size(ds*2, ds*2);
  8.     data = addData(ds, 200);
  9.     frameRate(10);
  10. }
  11. void draw() {
  12.    if (keyPressed == true) {
  13.      data = addData(ds, 300);
  14.    }
  15.     background(0);
  16.     for(int x=0;x<ds;x++)
  17.     {
  18.       for(int y=0;y<ds;y++)
  19.       {
  20.         try
  21.         {
  22.           int dataVal = (int)data[x][y];
  23.          
  24.           if(dataVal < -30)
  25.             fill(color(0, 0, 220));
  26.           else if(dataVal < 20)
  27.             fill(color(0, 0, 255));
  28.           else if(dataVal > 90 && dataVal < 370)
  29.             fill(color(15, 120, 0));
  30.           else if(dataVal < 90)
  31.             fill(color(15, 150, 0));
  32.           else if(dataVal > 370)
  33.             fill(color(255));
  34.          
  35.           noStroke();
  36.           rect(x*2, y*2, 2, 2 );
  37.         }
  38.         catch(NullPointerException e)
  39.         {
  40.          
  41.         }
  42.       }
  43.     }
  44. }
  45.  
  46. double[][] addData(int _size, double _seed) {
  47.     //size of grid to generate, note this must be a
  48.     //value 2^n+1
  49.     final int DATA_SIZE = _size;
  50.     //an initial seed value for the corners of the data
  51.     final double SEED = _seed;
  52.     double[][] data = new double[DATA_SIZE][DATA_SIZE];
  53.     //seed the data
  54.     data[0][0] = data[0][DATA_SIZE - 1] = data[DATA_SIZE - 1][0] =
  55.         data[DATA_SIZE - 1][DATA_SIZE - 1] = SEED;
  56.  
  57.     double h = 550; //the range (-h -> +h) for the average offset
  58.     Random r = new Random(); //for the new value in range of h
  59.     //side length is distance of a single square side
  60.     //or distance of diagonal in diamond
  61.     for (int sideLength = DATA_SIZE - 1;
  62.         //side length must be >= 2 so we always have
  63.         //a new value (if its 1 we overwrite existing values
  64.         //on the last iteration)
  65.         sideLength >= 2;
  66.         //each iteration we are looking at smaller squares
  67.         //diamonds, and we decrease the variation of the offset
  68.         sideLength /= 2, h /= 2.0) {
  69.         //half the length of the side of a square
  70.         //or distance from diamond center to one corner
  71.         //(just to make calcs below a little clearer)
  72.         int halfSide = sideLength / 2;
  73.         //generate the new square values
  74.         for (int x = 0; x < DATA_SIZE - 1; x += sideLength) {
  75.             for (int y = 0; y < DATA_SIZE - 1; y += sideLength) {
  76.                 //x, y is upper left corner of square
  77.                 //calculate average of existing corners
  78.                 double avg = data[x][y] + //top left
  79.                     data[x + sideLength][y] + //top right
  80.                     data[x][y + sideLength] + //lower left
  81.                     data[x + sideLength][y + sideLength]; //lower right
  82.                 avg /= 4.0;
  83.  
  84.                 //center is average plus random offset
  85.                 data[x + halfSide][y + halfSide] =
  86.                     //We calculate random value in range of 2h
  87.                     //and then subtract h so the end value is
  88.                     //in the range (-h, +h)
  89.                     avg + (r.nextDouble() * 2 * h) - h;
  90.             }
  91.         }
  92.  
  93.         //generate the diamond values
  94.         //since the diamonds are staggered we only move x
  95.         //by half side
  96.         //NOTE: if the data shouldn't wrap then x < DATA_SIZE
  97.         //to generate the far edge values
  98.         for (int x = 0; x < DATA_SIZE - 1; x += halfSide) {
  99.             //and y is x offset by half a side, but moved by
  100.             //the full side length
  101.             //NOTE: if the data shouldn't wrap then y < DATA_SIZE
  102.             //to generate the far edge values
  103.             for (int y = (x + halfSide) % sideLength; y < DATA_SIZE - 1; y += sideLength) {
  104.                 //x, y is center of diamond
  105.                 //note we must use mod  and add DATA_SIZE for subtraction
  106.                 //so that we can wrap around the array to find the corners
  107.                 double avg =
  108.                   data[(x-halfSide+DATA_SIZE-1)%(DATA_SIZE-1)][y] + //left of center
  109.                   data[(x+halfSide)%(DATA_SIZE-1)][y] + //right of center
  110.                   data[x][(y+halfSide)%(DATA_SIZE-1)] + //below center
  111.                   data[x][(y-halfSide+DATA_SIZE-1)%(DATA_SIZE-1)]; //above center
  112.                 avg /= 4.0;
  113.  
  114.                 //new value = average plus random offset
  115.                 //We calculate random value in range of 2h
  116.                 //and then subtract h so the end value is
  117.                 //in the range (-h, +h)
  118.                 avg = avg + (r.nextDouble() * 2 * h) - h;
  119.                 //update value for center of diamond
  120.                 data[x][y] = avg;
  121.  
  122.                 //wrap values on the edges, remove
  123.                 //this and adjust loop condition above
  124.                 //for non-wrapping values.
  125.                 if (x == 0) data[DATA_SIZE - 1][y] = avg;
  126.                 if (y == 0) data[x][DATA_SIZE - 1] = avg;
  127.             }
  128.         }
  129.     }
  130.    
  131.     return data;
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement