Guest User

Untitled

a guest
Jun 27th, 2012
979
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.util.Random;
  2.  
  3. public class PerlinNoise {
  4.  
  5.     final static int TABLE_SIZE = 64;
  6.  
  7.     private final static double WEIGHT(double T) {
  8.         return ((2.0 * Math.abs(T) - 3.0) * (T) * (T) + 1.0);
  9.     }
  10.  
  11.     private final int CLAMP(int val, int min, int max) {
  12.         return ((val < min ? min : val) > max ? max : val);
  13.     }
  14.  
  15.     private final double CLAMP(double val, double min, double max) {
  16.         return ((val < min ? min : val) > max ? max : val);
  17.     }
  18.  
  19.     final int SCALE_WIDTH = 128;
  20.     final double MIN_SIZE = 0.1;
  21.     final double MAX_SIZE = 16.0;
  22.  
  23.     private boolean tilable = false;
  24.     private boolean turbulent = false;
  25.     private long seed = 0;
  26.     private int detail = 1;
  27.     private double size = 8.0;
  28.  
  29.     private static int clip;
  30.     private static double offset, factor;
  31.     static int[] perm_tab = new int[TABLE_SIZE];
  32.     static Vector2d[] grad_tab = new Vector2d[TABLE_SIZE];
  33.  
  34.     public PerlinNoise(long seed) {
  35.         this.seed = seed;
  36.         init();
  37.     }
  38.  
  39.     public double noise2(double x, double y) {
  40.         x /= 100;
  41.         y /= 100;
  42.         return noise(x, y);
  43.     }
  44.  
  45.     void init() {
  46.         int i, j, k, t;
  47.         double m;
  48.         Random r;
  49.  
  50.         r = new Random(seed);
  51.  
  52.         /* Force sane parameters */
  53.         detail = CLAMP(detail, 0, 15);
  54.         size = CLAMP(size, MIN_SIZE, MAX_SIZE);
  55.  
  56.         /* Set scaling factors */
  57.         if (tilable) {
  58.             this.size = Math.ceil(size);
  59.             clip = (int) size;
  60.         }
  61.  
  62.         /* Set totally empiric normalization values */
  63.         if (turbulent) {
  64.             offset = 0.0;
  65.             factor = 1.0;
  66.         } else {
  67.             offset = 0.94;
  68.             factor = 0.526;
  69.         }
  70.  
  71.         /* Initialize the permutation table */
  72.         for (i = 0; i < TABLE_SIZE; i++)
  73.             perm_tab[i] = i;
  74.  
  75.         for (i = 0; i < (TABLE_SIZE >> 1); i++) {
  76.             j = r.nextInt(TABLE_SIZE);
  77.             k = r.nextInt(TABLE_SIZE);
  78.             t = perm_tab[j];
  79.             perm_tab[j] = perm_tab[k];
  80.             perm_tab[k] = t;
  81.         }
  82.  
  83.         /* Initialize the gradient table */
  84.         for (i = 0; i < TABLE_SIZE; i++) {
  85.             grad_tab[i] = new Vector2d();
  86.             do {
  87.                 grad_tab[i].setX((r.nextDouble() * 2) - 1);
  88.                 grad_tab[i].setY((r.nextDouble() * 2) - 1);
  89.                 m = grad_tab[i].getX() * grad_tab[i].getX() + grad_tab[i].getY() * grad_tab[i].getY();
  90.             } while (m == 0.0 || m > 1.0);
  91.  
  92.             m = 1.0 / Math.sqrt(m);
  93.             grad_tab[i].setX(grad_tab[i].getX() * m);
  94.             grad_tab[i].setY(grad_tab[i].getY() * m);
  95.         }
  96.  
  97.         r = null;
  98.     }
  99.  
  100.     double plain_noise(double x, double y, int s) {
  101.         Vector2d v = new Vector2d();
  102.         int a, b, i, j, n;
  103.         double sum;
  104.  
  105.         sum = 0.0;
  106.         x *= s;
  107.         y *= s;
  108.         a = (int) Math.floor(x);
  109.         b = (int) Math.floor(y);
  110.  
  111.         for (i = 0; i < 2; i++)
  112.             for (j = 0; j < 2; j++) {
  113.                 if (tilable)
  114.                     n = perm_tab[betterMod((betterMod((a + i), (clip * s)) + perm_tab[betterMod(betterMod((b + j), (clip * s)), TABLE_SIZE)]), TABLE_SIZE)];
  115.                 else
  116.                     n = perm_tab[betterMod(a + i + perm_tab[betterMod(b + j, TABLE_SIZE)], TABLE_SIZE)];
  117.                 v.setX(x - a - i);
  118.                 v.setY(y - b - j);
  119.                 sum += WEIGHT(v.getX()) * WEIGHT(v.getY()) * (grad_tab[n].getX() * v.getX() + grad_tab[n].getY() * v.getY());
  120.             }
  121.  
  122.         return sum / s;
  123.     }
  124.        
  125.         /** Modified modulus, so that negative numbers wrap correctly! */
  126.     private int betterMod(int val, int range) {
  127.         return (val % range + range) % range;
  128.     }
  129.  
  130.     double noise(double x, double y) {
  131.         int i;
  132.         int s;
  133.         double sum;
  134.  
  135.         s = 1;
  136.         sum = 0.0;
  137.         x *= size;
  138.         y *= size;
  139.  
  140.         for (i = 0; i <= detail; i++) {
  141.             if (turbulent)
  142.                 sum += Math.abs(plain_noise(x, y, s));
  143.             else
  144.                 sum += plain_noise(x, y, s);
  145.             s <<= 1;
  146.         }
  147.  
  148.         return (sum + offset) * factor;
  149.     }
  150. }
RAW Paste Data