Morph-SynRJ
view mth_perlin.cxx @ 0:22de913c2d84
morph-synrj intro
| author | "Cedric Pinson <cedric.pinson@alcove.fr> <mornifle@plopbyte.net>" |
|---|---|
| date | Tue Nov 27 15:23:52 2007 +0100 (2007-11-27) |
| parents | |
| children |
line source
1 /** @file mth_perlin.cxx
2 *
3 * @brief perlin noise class
4 *
5 *****************************************************************************
6 *
7 * @author STV & psc80
8 *
9 * @date Created 2003/08
10 *
11 * @version $Id: mth_perlin.cxx,v 1.3 2004/01/10 22:38:31 psc80 Exp $
12 *
13 ****************************************************************************/
15 #include "mth_perlin.h"
17 /* coherent noise function over 1, 2 or 3 dimensions */
18 /* (copyright Ken Perlin) */
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
25 namespace mth {
29 #define B 0x100
30 #define BM 0xff
32 #define N 0x1000
33 #define NP 12 /* 2^N */
34 #define NM 0xfff
36 static p[B + B + 2];
37 static float g3[B + B + 2][3];
38 static float g2[B + B + 2][2];
39 static float g1[B + B + 2];
40 static start = 1;
42 static void init(void);
44 #define s_curve(t) ( t * t * (3. - 2. * t) )
46 #define lerp(t, a, b) ( a + t * (b - a) )
48 void setup(int i,float* vec,float& t,int& b0,int& b1,float& r0,float& r1)
49 {
50 t = vec[i] + N;
51 b0 = ((int)t) & BM;
52 b1 = (b0+1) & BM;
53 r0 = t - (int)t;
54 r1 = r0 - 1.;
55 }
57 double noise1(double arg)
58 {
59 int bx0, bx1;
60 float rx0, rx1, sx, t, u, v, vec[1];
62 vec[0] = arg;
63 if (start) {
64 start = 0;
65 init();
66 }
68 // setup(0, bx0,bx1, rx0,rx1);
70 sx = s_curve(rx0);
72 u = rx0 * g1[ p[ bx0 ] ];
73 v = rx1 * g1[ p[ bx1 ] ];
75 return lerp(sx, u, v);
76 }
78 float noise2(float vec[2])
79 {
80 int bx0, bx1, by0, by1, b00, b10, b01, b11;
81 float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
82 register i, j;
84 if (start) {
85 start = 0;
86 init();
87 }
89 setup(0,vec,t,bx0,bx1, rx0,rx1);
90 setup(1,vec,t, by0,by1, ry0,ry1);
92 i = p[ bx0 ];
93 j = p[ bx1 ];
95 b00 = p[ i + by0 ];
96 b10 = p[ j + by0 ];
97 b01 = p[ i + by1 ];
98 b11 = p[ j + by1 ];
100 sx = s_curve(rx0);
101 sy = s_curve(ry0);
103 #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
105 q = g2[ b00 ] ; u = at2(rx0,ry0);
106 q = g2[ b10 ] ; v = at2(rx1,ry0);
107 a = lerp(sx, u, v);
109 q = g2[ b01 ] ; u = at2(rx0,ry1);
110 q = g2[ b11 ] ; v = at2(rx1,ry1);
111 b = lerp(sx, u, v);
113 return lerp(sy, a, b);
114 }
116 float noise3(float vec[3])
117 {
118 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
119 float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
120 register i, j;
122 if (start) {
123 start = 0;
124 init();
125 }
127 // setup(0, bx0,bx1, rx0,rx1);
128 // setup(1, by0,by1, ry0,ry1);
129 // setup(2, bz0,bz1, rz0,rz1);
131 i = p[ bx0 ];
132 j = p[ bx1 ];
134 b00 = p[ i + by0 ];
135 b10 = p[ j + by0 ];
136 b01 = p[ i + by1 ];
137 b11 = p[ j + by1 ];
139 t = s_curve(rx0);
140 sy = s_curve(ry0);
141 sz = s_curve(rz0);
143 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
145 q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
146 q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
147 a = lerp(t, u, v);
149 q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
150 q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
151 b = lerp(t, u, v);
153 c = lerp(sy, a, b);
155 q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
156 q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
157 a = lerp(t, u, v);
159 q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
160 q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
161 b = lerp(t, u, v);
163 d = lerp(sy, a, b);
165 return lerp(sz, c, d);
166 }
168 static void normalize2(float v[2])
169 {
170 float s;
172 s = Sqrt(v[0] * v[0] + v[1] * v[1]);
173 v[0] = v[0] / s;
174 v[1] = v[1] / s;
175 }
177 static void normalize3(float v[3])
178 {
179 float s;
181 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
182 v[0] = v[0] / s;
183 v[1] = v[1] / s;
184 v[2] = v[2] / s;
185 }
187 static void init(void)
188 {
189 int i, j, k;
191 for (i = 0 ; i < B ; i++) {
192 p[i] = i;
194 g1[i] = (float)((Random() % (B + B)) - B) / B;
196 for (j = 0 ; j < 2 ; j++)
197 g2[i][j] = (float)((Random() % (B + B)) - B) / B;
198 normalize2(g2[i]);
200 for (j = 0 ; j < 3 ; j++)
201 g3[i][j] = (float)((Random() % (B + B)) - B) / B;
202 normalize3(g3[i]);
203 }
205 while (--i) {
206 k = p[i];
207 p[i] = p[j = Random() % B];
208 p[j] = k;
209 }
211 for (i = 0 ; i < B + 2 ; i++) {
212 p[B + i] = p[i];
213 g1[B + i] = g1[i];
214 for (j = 0 ; j < 2 ; j++)
215 g2[B + i][j] = g2[i][j];
216 for (j = 0 ; j < 3 ; j++)
217 g3[B + i][j] = g3[i][j];
218 }
219 }
223 float noise2d(float _x,float _y)
224 {
225 float a[2]={_x,_y};
226 return noise2(a);
227 }
231 }
