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__ */