package game; public class PerlinNoise2D { private static float noise(int x, int y) { int n = x + y * 57; n = (n << 13) ^ n; return (1.0f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f); } private static float smoothNoise(float x, float y) { float corners = (noise((int)x - 1, (int)y - 1) + noise((int)x - 1, (int)y + 1) + noise((int)x + 1, (int)y + 1)) / 16; float sides = (noise((int)x - 1, (int)y) + noise((int)x + 1, (int)y) + noise((int)x, (int)y + 1)) / 8; float center = noise((int)x, (int)y) / 4; return corners + sides + center; } private static float cosInterpolate(float a, float b, float x) { float angle = (float) (x * Math.PI); float prc = (float) ((1.0f - Math.cos(angle)) * 0.5f); return a * (1.0f - prc) + b * prc; } public static float perlin2D(int x, int y, int width, int height, int seed, float noiseSize, float persistence, int octaves) { float total = 0.0f; x = x + 2000000; y = y + 2000000; for(int i = 1; i <= octaves; i++) { // Calculate frequency and amplitude float freq = (float) Math.pow(2, i); float amp = (float) Math.pow(persistence, i); // Calculate x and y noise coordinates float tx = x * freq * noiseSize / i; float ty = y * freq * noiseSize / i; float txInt = (int) tx; float tyInt = (int) ty; // Calculate fractions of x and y float fracX = tx - txInt; float fracY = ty - tyInt; // Get noise float v1 = smoothNoise(txInt + seed, tyInt + seed); float v2 = smoothNoise(txInt + 1 + seed, tyInt + seed); float v3 = smoothNoise(txInt + seed, tyInt + 1 + seed); float v4 = smoothNoise(txInt + 1 + seed, tyInt + 1 + seed); // Smooth noise in the X-axis float i1 = cosInterpolate(v1, v2, fracX); float i2 = cosInterpolate(v3, v4, fracX); // Smooth in the Y-axis total += cosInterpolate(i1, i2, fracY) * amp; } return total; } }