Java examples for java.lang:Math Algorithm
A fast implementation of fractional Brownian motion.
/*/*from w ww . j a v a 2 s. c o m*/ * A Java Utility Library * * Copyright (C) 2010-2012 Jan Graichen <jg@altimos.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * See the NOTICE file distributed along with this work for further * information. */ //package com.java2s; public class Main { public static int p[] = new int[512]; /** * A fast implementation of fractional Brownian motion. * This implementation assumes an integer number of octaves and * a lacunarity of two. This simplification is done for speed. */ public static double fBm(double x, double y, double z, int H, int octaves) { double sum = 0; for (int i = 0; i < octaves; i++) { sum += noise(x, y, z) / (1 << H * i); x *= 2; y *= 2; z *= 2; } return sum; } public static float fBm(float x, float y, float z, int octaves, float lacunarity, float gain) { float sum = 0; float amp = 1; for (int i = 0; i < octaves; i++) { sum += amp * noiseF(x, y, z); x *= lacunarity; y *= lacunarity; z *= lacunarity; amp *= gain; } return sum; } public static double noise(double x, double y, double z) { double a = Math.floor(x); double b = Math.floor(y); double c = Math.floor(z); int X = (int) a & 255; int Y = (int) b & 255; int Z = (int) c & 255; x -= a; y -= b; z -= c; int A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z; int B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; double u = fade(x); double v = fade(y); double w = fade(z); return mix( w, mix(v, mix(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z)), mix(u, grad(p[AB], x, y - 1, z), grad(p[BB], x - 1, y - 1, z))), mix(v, mix(u, grad(p[AA + 1], x, y, z - 1), grad(p[BA + 1], x - 1, y, z - 1)), mix(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1)))); } public static float noiseF(float x, float y, float z) { // Sourced this computation out to gain performance: double a = Math.floor(x); double b = Math.floor(y); double c = Math.floor(z); int X = (int) a & 255; int Y = (int) b & 255; int Z = (int) c & 255; x -= a; y -= b; z -= c; int A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z; int B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; float u = fadeF(x); float v = fadeF(y); float w = fadeF(z); return mixF( w, mixF(v, mixF(u, gradF(p[AA], x, y, z), gradF(p[BA], x - 1, y, z)), mixF(u, gradF(p[AB], x, y - 1, z), gradF(p[BB], x - 1, y - 1, z))), mixF(v, mixF(u, gradF(p[AA + 1], x, y, z - 1), gradF(p[BA + 1], x - 1, y, z - 1)), mixF(u, gradF(p[AB + 1], x, y - 1, z - 1), gradF(p[BB + 1], x - 1, y - 1, z - 1)))); } /** * Uses a fifth order polynom to avoid the second order discontinuity */ private static double fade(double x) { return x * x * x * (x * (x * 6 - 15) + 10); } /** * Performs a linear blend operation of a and b based on t */ public static double mix(double x, double a, double b) { return a + x * (b - a); } /** * This function are using a hard-coded switch-statement-table * to determine the result only based on corners hash value. * * This is up to 3 times faster the Ken Perlins original approach! */ private static double grad(int hash, double x, double y, double z) { switch (hash & 15) { case 0: return x + y; case 1: return -x + y; case 2: return x - y; case 3: return -x - y; case 4: return x + z; case 5: return -x + z; case 6: return x - z; case 7: return -x - z; case 8: return y + z; case 9: return -y + z; case 10: return y - z; case 11: return -y - z; case 12: return x + y; case 13: return -y + z; case 14: return -x + y; case 15: return -y - z; } throw new IllegalArgumentException("Should never reach here!"); } private static float fadeF(float x) { return x * x * x * (x * (x * 6 - 15) + 10); } public static float mixF(float x, float a, float b) { return a + x * (b - a); } /** * This function are using a hard-coded switch-statement-table * to determine the result only based on corners hash value. * * This is up to 3 times faster the Ken Perlins original approach! */ private static float gradF(int hash, float x, float y, float z) { switch (hash & 15) { case 0: return x + y; case 1: return -x + y; case 2: return x - y; case 3: return -x - y; case 4: return x + z; case 5: return -x + z; case 6: return x - z; case 7: return -x - z; case 8: return y + z; case 9: return -y + z; case 10: return y - z; case 11: return -y - z; case 12: return x + y; case 13: return -y + z; case 14: return -x + y; case 15: return -y - z; } throw new IllegalArgumentException("Should never reach here!"); } }