Source code: org/maloi/evolvo/expressiontree/operators/WarpedNoise.java
1 /* Evolvo - Image Generator
2 * Copyright (C) 2000 Andrew Molloy
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /**
20 * $Id: WarpedNoise.java,v 1.1.1.1 2002/10/04 15:39:32 maloi Exp $
21 */
22
23 package org.maloi.evolvo.expressiontree.operators;
24
25 import java.io.Serializable;
26 import java.util.Random;
27
28 import org.maloi.evolvo.expressiontree.vm.Stack;
29
30 /**
31 * Returns the value of a point in a 3 dimensional noise field.
32 */
33 public class WarpedNoise implements OperatorInterface, Serializable
34 {
35 /** The maximum size of the noise field. */
36 static int maxNoise = 100;
37 /** An array of data points in the noise field. */
38 static double noiseTable[][][] = new double[maxNoise][maxNoise][maxNoise];
39
40 /** Performs any initialization the operator requires.
41 * In this case, generates a 3d array of random values. */
42 public void init()
43 {
44 int ix, iy, iz;
45 int xx, yy, zz;
46
47 Random r = new Random();
48
49 for (ix = 0; ix < maxNoise; ix++)
50 {
51 for (iy = 0; iy < maxNoise; iy++)
52 {
53 for (iz = 0; iz < maxNoise; iz++)
54 {
55 noiseTable[ix][iy][iz] = r.nextDouble() * 2.0 - 1.0;
56 if (ix == maxNoise)
57 {
58 xx = 0;
59 }
60 else
61 {
62 xx = ix;
63 }
64 if (iy == maxNoise)
65 {
66 yy = 0;
67 }
68 else
69 {
70 yy = iy;
71 }
72 if (iz == maxNoise)
73 {
74 zz = 0;
75 }
76 else
77 {
78 zz = iz;
79 }
80 noiseTable[ix][iy][iz] = noiseTable[xx][yy][zz];
81 }
82 }
83 }
84 }
85
86 /** Returns the fractional part of a double. */
87 double frac(double r)
88 {
89 return (r - (double) (int) r);
90 }
91
92 /** Perform the operation. */
93 public void perform(Stack theStack)
94 {
95 int xx, yy, zz;
96 double x, y, z;
97 int ix, iy, iz;
98 double ox, oy, oz;
99 double n;
100 double n00, n01, n10, n11;
101 double n0, n1;
102
103 // First we evaluate each parameter, and find an x, y, and z value in
104 // [0,maxNoise-2]
105 x = ((theStack.pop() * theStack.pop() + 1.0) / 2.0) * (maxNoise - 2.0);
106 y = ((theStack.pop() * theStack.pop() + 1.0) / 2.0) * (maxNoise - 2.0);
107 z = ((theStack.pop() * theStack.pop() + 1.0) / 2.0) * (maxNoise - 2.0);
108
109 // Move the x,y,z values to integer space
110 ix = (int) x % (maxNoise - 2) + 1;
111 iy = (int) y % (maxNoise - 2) + 1;
112 iz = (int) z % (maxNoise - 2) + 1;
113
114 // Get the fractional part of each x,y, and z
115 ox = frac(x);
116 oy = frac(y);
117 oz = frac(z);
118
119 // First we get the values in the noise table that surround the actual
120 // point (x,y,z)
121 n = noiseTable[ix][iy][iz];
122 n00 = n + ox * (noiseTable[ix + 1][iy][iz] - n);
123 n = noiseTable[ix][iy][iz + 1];
124 n01 = n + ox * (noiseTable[ix + 1][iy][iz - 1] - n);
125 n = noiseTable[ix][iy + 1][iz];
126 n10 = n + ox * (noiseTable[ix + 1][iy + 1][iz] - n);
127 n = noiseTable[ix][iy + 1][iz + 1];
128 n11 = n + ox * (noiseTable[ix + 1][iy + 1][iz + 1] - n);
129
130 n0 = n00 + oy * (n10 - n00);
131 n1 = n01 + oy * (n11 - n01);
132
133 theStack.push((n0 + oz * (n1 - n0)));
134 // Return a value linearly interpolated from the noise tabled
135 }
136
137 /** Returns the operator's name. */
138 public String getName()
139 {
140 return "warpednoise";
141 }
142
143 /** Returns the number of parameters expected by the operator. */
144 public int getNumberOfParameters()
145 {
146 return 6;
147 }
148 }