View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components.gauger;
21  
22  /**
23   * Simple class to generate perlin noise signal.
24   *
25   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
26   * @version $id$
27   */
28  public class NoiseMaker
29  {
30  	/**
31  	 * Pseudo-random generator function. Returns random value at given time.
32  	 * This function will return pseudo-random values for increasing time, but
33  	 * always same value for same time.
34  	 *
35  	 * @param x time.
36  	 *
37  	 * @return Random value at given time.
38  	 */
39  	public static final double noise(long x)
40  	{
41  		x ^= (x << 13);
42  
43  		return (1.0
44  		- ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
45  	}
46  
47  	/**
48  	 * Returns gaussian averaged noise value sampled over three time units.
49  	 *
50  	 * @param x time offset.
51  	 *
52  	 * @return Smoothed noise value.
53  	 */
54  	public static final double smoothedNoise(final long x)
55  	{
56  		return noise(x) * 0.5 + 0.25 * (noise(x - 1) + noise(x + 1));
57  	}
58  
59  	/**
60  	 * Returns cosine interpolated noise value between two integral time units.
61  	 *
62  	 * @param x time.
63  	 *
64  	 * @return Interpolated noise value at time x between floor(x) and ceil(x)
65  	 */
66  	public static final double interpolatedNoise(final double x)
67  	{
68  		final long intX = (long)x;
69  
70  		double n1 = noise(intX);
71  		double n2 = noise(intX + 1);
72  
73  		double v1 = (noise(intX - 1) + n2) * 0.25 + n1 * 0.5;
74  		double v2 = (noise(intX + 2) + n1) * 0.25 + n2 * 0.5;
75  
76  		return v1 + (v2 - v1) * (1 - Math.cos((x - intX) * Math.PI)) * 0.5;
77  	}
78  
79  	/**
80  	 * Returns pseudo random noise signal at given value. For a given parameter
81  	 * x the return value will always be the same, but for increasing values,
82  	 * return value will be seemingly random smoothed noise.
83  	 *
84  	 * @param x Time at which to sample the noise.
85  	 *
86  	 * @return Value of signal.
87  	 */
88  	public static final double perlinNoise(final double x)
89  	{
90  		double total = 0;
91  		double n = 6;
92  		double frequency = 1;
93  
94  		for(int i = 0; i < n; i++) {
95  			total += interpolatedNoise(x * frequency);
96  
97  			frequency *= 2;
98  		}
99  
100 		return total / n;
101 	}
102 
103 	/**
104 	 * Simple test method.
105 	 *
106 	 * @param args Not used.
107 	 */
108 	public static void main(String[] args)
109 	{
110 		double min = Double.MAX_VALUE;
111 		double max = Double.MIN_VALUE;
112 		double c = 0;
113 
114 		for(int i = 0; i < 10000000; i++) {
115 			c = perlinNoise(i);
116 
117 			if(c < min) {
118 				min = c;
119 				System.out.println("Minimum = " + min + ", Maximum = " + max);
120 			}
121 
122 			if(c > max) {
123 				max = c;
124 				System.out.println("Minimum = " + min + ", Maximum = " + max);
125 			}
126 		}
127 	}
128 }
129 
130 /* __oOo__ */