From 26f446eb33bd10486c0e4d14cc4fb1d557d21679 Mon Sep 17 00:00:00 2001 From: kromzem Date: Wed, 25 Oct 2017 15:22:16 +0200 Subject: [PATCH] added "Perlin-Noise-Algorithm" --- Others/PerlinNoise.java | 129 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/Others/PerlinNoise.java b/Others/PerlinNoise.java index 8b1378917..d8e04a857 100644 --- a/Others/PerlinNoise.java +++ b/Others/PerlinNoise.java @@ -1 +1,130 @@ +import java.util.Random; +import java.util.Scanner; +public class PerlinNoise { + static float[][] generatePerlinNoise(int width, int height, int octaveCount, float persistence, long seed) { + final float[][] base = new float[width][height]; + final float[][] perlinNoise = new float[width][height]; + final float[][][] noiseLayers = new float[octaveCount][][]; + + Random random = new Random(seed); + for(int x = 0; x < width; x++) { + for(int y = 0; y < height; y++) { + base[x][y] = random.nextFloat(); + } + } + + //calculate octaves + for(int octave = 0; octave < octaveCount; octave++) { + noiseLayers[octave] = generatePerlinNoiseLayer(base, width, height, octave); + } + + float amplitude = 1f; + float totalAmplitude = 0f; + + //calculate perlin noise + for(int octave = octaveCount - 1; octave >= 0; octave--) { + amplitude *= persistence; + totalAmplitude += amplitude; + + for(int x = 0; x < width; x++) { + for(int y = 0; y < height; y++) { + perlinNoise[x][y] += noiseLayers[octave][x][y] * amplitude; + } + } + } + + //normalize + for(int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + perlinNoise[x][y] /= totalAmplitude; + } + } + + return perlinNoise; + } + + static float[][] generatePerlinNoiseLayer(float[][] base, int width, int height, int octave) { + float[][] perlinNoiseLayer = new float[width][height]; + + int period = 1 << octave; + float frequency = 1f / period; + + for(int x = 0; x < width; x++) { + int x0 = (x / period) * period; + int x1 = (x0 + period) % width; + float horizintalBlend = (x - x0) * frequency; + + for(int y = 0; y < height; y++) { + int y0 = (y / period) * period; + int y1 = (y0 + period) % height; + float verticalBlend = (y - y0) * frequency; + + float top = interpolate(base[x0][y0], base[x1][y0], horizintalBlend); + float bottom = interpolate(base[x0][y1], base[x1][y1], horizintalBlend); + + perlinNoiseLayer[x][y] = interpolate(top, bottom, verticalBlend); + } + } + + return perlinNoiseLayer; + } + + static float interpolate(float a, float b, float alpha) { + return a * (1 - alpha) + alpha * b; + } + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + + final int width; + final int height; + final int octaveCount; + final float persistence; + final long seed; + final String charset; + final float[][] perlinNoise; + + System.out.println("Width (int): "); + width = in.nextInt(); + + System.out.println("Height (int): "); + height = in.nextInt(); + + System.out.println("Octave count (int): "); + octaveCount = in.nextInt(); + + System.out.println("Persistence (float): "); + persistence = in.nextFloat(); + + System.out.println("Seed (long): "); + seed = in.nextLong(); + + System.out.println("Charset (String): "); + charset = in.next(); + + + perlinNoise = generatePerlinNoise(width, height, octaveCount, persistence, seed); + final char[] chars = charset.toCharArray(); + final int length = chars.length; + final float step = 1f / length; + //output based on charset + for(int x = 0; x < width; x++) { + for(int y = 0; y < height; y++) { + float value = step; + float noiseValue = perlinNoise[x][y]; + + for (char c : chars) { + if (noiseValue <= value) { + System.out.print(c); + break; + } + + value += step; + } + } + + System.out.println(); + } + } +}