//This is the recursive function that implements the random midpoint //displacement algorithm. It will call itself until the grid pieces //become smaller than one pixel. private static void DivideGrid(Matrix matrix, RandomGeneratorXorShift rnd, int x, int y, int size, int c1, int c2, int c3, int c4, int roughness) { int Edge1, Edge2, Edge3, Edge4, Middle; if (size > 1) { int newSize = size / 2; Middle = (c1 + c2 + c3 + c4) / 4 + Displace(rnd, newSize, roughness); //Randomly displace the midpoint! Edge1 = (c1 + c2) / 2; Edge2 = (c2 + c3) / 2; Edge3 = (c3 + c4) / 2; Edge4 = (c4 + c1) / 2; //Make sure that the midpoint doesn't accidentally "randomly displaced" past the boundaries! if (Middle < 0) Middle = 0; else if (Middle > 255) Middle = 255; //Do the operation over again for each of the four new grids. DivideGrid(matrix, rnd, x, y, newSize, c1, Edge1, Middle, Edge4, roughness); DivideGrid(matrix, rnd, x + newSize, y, newSize, Edge1, c2, Edge2, Middle, roughness); DivideGrid(matrix, rnd, x + newSize, y + newSize, newSize, Middle, Edge2, c3, Edge3, roughness); DivideGrid(matrix, rnd, x, y + newSize, newSize, Edge4, Middle, Edge3, c4, roughness); } else //This is the "base case," where each grid piece is less than the size of a pixel. { //The four corners of the grid piece will be averaged and drawn as a single pixel. int c = (c1 + c2 + c3 + c4) / 4; matrix.SetValue(x, y, (byte) c); } }
//This is something of a "helper function" to create an initial grid //before the recursive function is called. public static void DrawPlasma(Matrix matrix, int seed, int roughness) { if (roughness < 1) roughness = 1; int c1, c2, c3, c4; RandomGeneratorXorShift rnd = new RandomGeneratorXorShift(seed); //Assign the four corners of the intial grid random color values //These will end up being the colors of the four corners of the applet. c1 = rnd.Range(0, 256); c2 = rnd.Range(0, 256); c3 = rnd.Range(0, 256); c4 = rnd.Range(0, 256); DivideGrid(matrix, rnd, 0, 0, matrix.size, c1, c2, c3, c4, roughness); }
//This is something of a "helper function" to create an initial grid //before the recursive function is called. static public void DrawPlasma(Matrix matrix, int seed, int roughness) { if (roughness < 1) { roughness = 1; } int c1, c2, c3, c4; RandomGeneratorXorShift rnd = new RandomGeneratorXorShift(seed); //Assign the four corners of the intial grid random color values //These will end up being the colors of the four corners of the applet. c1 = rnd.Range(0, 256); c2 = rnd.Range(0, 256); c3 = rnd.Range(0, 256); c4 = rnd.Range(0, 256); DivideGrid(matrix, rnd, 0, 0, matrix.size, c1, c2, c3, c4, roughness); }
public PerlinNoiseFixed(int seed) { RandomGeneratorXorShift rnd = new RandomGeneratorXorShift(seed); int i, j, k; for (i = 0; i < B; i++) { m_perm[i] = i; } while (--i != 0) { k = m_perm[i]; j = rnd.Range(0, B); m_perm[i] = m_perm[j]; m_perm[j] = k; } for (i = 0; i < B; i++) { m_perm[B + i] = m_perm[i]; } }
//This is the recursive function that implements the random midpoint //displacement algorithm. It will call itself until the grid pieces //become smaller than one pixel. static private void DivideGrid(Matrix matrix, RandomGeneratorXorShift rnd, int x, int y, int size, int c1, int c2, int c3, int c4, int roughness) { int Edge1, Edge2, Edge3, Edge4, Middle; if (size > 1) { int newSize = size / 2; Middle = (c1 + c2 + c3 + c4) / 4 + Displace(rnd, newSize, roughness); //Randomly displace the midpoint! Edge1 = (c1 + c2) / 2; Edge2 = (c2 + c3) / 2; Edge3 = (c3 + c4) / 2; Edge4 = (c4 + c1) / 2; //Make sure that the midpoint doesn't accidentally "randomly displaced" past the boundaries! if (Middle < 0) { Middle = 0; } else if (Middle > 255) { Middle = 255; } //Do the operation over again for each of the four new grids. DivideGrid(matrix, rnd, x, y, newSize, c1, Edge1, Middle, Edge4, roughness); DivideGrid(matrix, rnd, x + newSize, y, newSize, Edge1, c2, Edge2, Middle, roughness); DivideGrid(matrix, rnd, x + newSize, y + newSize, newSize, Middle, Edge2, c3, Edge3, roughness); DivideGrid(matrix, rnd, x, y + newSize, newSize, Edge4, Middle, Edge3, c4, roughness); } else //This is the "base case," where each grid piece is less than the size of a pixel. { //The four corners of the grid piece will be averaged and drawn as a single pixel. int c = (c1 + c2 + c3 + c4) / 4; matrix.SetValue(x, y, (byte)c); } }
public PerlinNoise(int seed) { RandomGeneratorXorShift rnd = new RandomGeneratorXorShift(seed); int i, j, k; for (i = 0; i < B; i++) { m_perm[i] = i; } while (--i != 0) { k = m_perm[i]; j = rnd.Range(0, B); m_perm[i] = m_perm[j]; m_perm[j] = k; } for (i = 0; i < B; i++) { m_perm[B + i] = m_perm[i]; } }
//Randomly displaces color value for midpoint depending on size //of grid piece. static int Displace(RandomGeneratorXorShift rnd, int num, int roughness) { return rnd.Range((-num * roughness) / 2 , (num * roughness) / 2 + 1); }
//Randomly displaces color value for midpoint depending on size //of grid piece. static int Displace(RandomGeneratorXorShift rnd, int num, int roughness) { return(rnd.Range((-num * roughness) / 2, (num * roughness) / 2 + 1)); }