1 /* coherent noise function over 1, 2 or 3 dimensions */
2 /* (copyright Ken Perlin) */
3 
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <math.h>
7 #include <time.h>
8 
9 #include "perlin.h"
10 
11 #define B SAMPLE_SIZE
12 #define BM (SAMPLE_SIZE-1)
13 
14 #define N 0x1000
15 #define NP 12   /* 2^N */
16 #define NM 0xfff
17 
18 #define s_curve(t) ( t * t * (3.0f - 2.0f * t) )
19 #define lerp(t, a, b) ( a + t * (b - a) )
20 
21 #define setup(i,b0,b1,r0,r1)\
22 	t = vec[i] + N;\
23 	b0 = ((int)t) & BM;\
24 	b1 = (b0+1) & BM;\
25 	r0 = t - (int)t;\
26 	r1 = r0 - 1.0f;
27 
noise1(float arg)28 float Perlin::noise1(float arg)
29 {
30 	int bx0, bx1;
31 	float rx0, rx1, sx, t, u, v, vec[1];
32 
33 	vec[0] = arg;
34 
35 	if (mStart)
36   {
37     srand(mSeed);
38 		mStart = false;
39 		init();
40 	}
41 
42 	setup(0, bx0,bx1, rx0,rx1);
43 
44 	sx = s_curve(rx0);
45 
46 	u = rx0 * g1[ p[ bx0 ] ];
47 	v = rx1 * g1[ p[ bx1 ] ];
48 
49 	return lerp(sx, u, v);
50 }
51 
noise2(float vec[2])52 float Perlin::noise2(float vec[2])
53 {
54 	int bx0, bx1, by0, by1, b00, b10, b01, b11;
55 	float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
56 	int i, j;
57 
58 	if (mStart)
59   {
60     srand(mSeed);
61 		mStart = false;
62 		init();
63 	}
64 
65 	setup(0,bx0,bx1,rx0,rx1);
66 	setup(1,by0,by1,ry0,ry1);
67 
68 	i = p[bx0];
69 	j = p[bx1];
70 
71 	b00 = p[i + by0];
72 	b10 = p[j + by0];
73 	b01 = p[i + by1];
74 	b11 = p[j + by1];
75 
76 	sx = s_curve(rx0);
77 	sy = s_curve(ry0);
78 
79   #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
80 
81 	q = g2[b00];
82 	u = at2(rx0,ry0);
83 	q = g2[b10];
84 	v = at2(rx1,ry0);
85 	a = lerp(sx, u, v);
86 
87 	q = g2[b01];
88 	u = at2(rx0,ry1);
89 	q = g2[b11];
90 	v = at2(rx1,ry1);
91 	b = lerp(sx, u, v);
92 
93 	return lerp(sy, a, b);
94 }
95 
noise3(float vec[3])96 float Perlin::noise3(float vec[3])
97 {
98 	int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
99 	float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
100 	int i, j;
101 
102 	if (mStart)
103   {
104     srand(mSeed);
105 		mStart = false;
106 		init();
107 	}
108 
109 	setup(0, bx0,bx1, rx0,rx1);
110 	setup(1, by0,by1, ry0,ry1);
111 	setup(2, bz0,bz1, rz0,rz1);
112 
113 	i = p[ bx0 ];
114 	j = p[ bx1 ];
115 
116 	b00 = p[ i + by0 ];
117 	b10 = p[ j + by0 ];
118 	b01 = p[ i + by1 ];
119 	b11 = p[ j + by1 ];
120 
121 	t  = s_curve(rx0);
122 	sy = s_curve(ry0);
123 	sz = s_curve(rz0);
124 
125   #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
126 
127 	q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
128 	q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
129 	a = lerp(t, u, v);
130 
131 	q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
132 	q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
133 	b = lerp(t, u, v);
134 
135 	c = lerp(sy, a, b);
136 
137 	q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
138 	q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
139 	a = lerp(t, u, v);
140 
141 	q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
142 	q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
143 	b = lerp(t, u, v);
144 
145 	d = lerp(sy, a, b);
146 
147 	return lerp(sz, c, d);
148 }
149 
normalize2(float v[2])150 void Perlin::normalize2(float v[2])
151 {
152 	float s;
153 
154 	s = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
155   s = 1.0f/s;
156 	v[0] = v[0] * s;
157 	v[1] = v[1] * s;
158 }
159 
normalize3(float v[3])160 void Perlin::normalize3(float v[3])
161 {
162 	float s;
163 
164 	s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
165   s = 1.0f/s;
166 
167 	v[0] = v[0] * s;
168 	v[1] = v[1] * s;
169 	v[2] = v[2] * s;
170 }
171 
init(void)172 void Perlin::init(void)
173 {
174 	int i, j, k;
175 
176 	for (i = 0 ; i < B ; i++)
177   {
178 		p[i] = i;
179 		g1[i] = (float)((rand() % (B + B)) - B) / B;
180 		for (j = 0 ; j < 2 ; j++)
181 			g2[i][j] = (float)((rand() % (B + B)) - B) / B;
182 		normalize2(g2[i]);
183 		for (j = 0 ; j < 3 ; j++)
184 			g3[i][j] = (float)((rand() % (B + B)) - B) / B;
185 		normalize3(g3[i]);
186 	}
187 
188 	while (--i)
189   {
190 		k = p[i];
191 		p[i] = p[j = rand() % B];
192 		p[j] = k;
193 	}
194 
195 	for (i = 0 ; i < B + 2 ; i++)
196   {
197 		p[B + i] = p[i];
198 		g1[B + i] = g1[i];
199 		for (j = 0 ; j < 2 ; j++)
200 			g2[B + i][j] = g2[i][j];
201 		for (j = 0 ; j < 3 ; j++)
202 			g3[B + i][j] = g3[i][j];
203 	}
204 
205 }
206 
207 
perlin_noise_2D(float vec[2])208 float Perlin::perlin_noise_2D(float vec[2])
209 {
210   int terms    = mOctaves;
211 	float freq   = mFrequency;
212 	float result = 0.0f;
213   float amp = mAmplitude;
214 
215   vec[0]*=freq;
216   vec[1]*=freq;
217 
218 	for( int i=0; i<terms; i++ )
219 	{
220 		result += noise2(vec)*amp;
221 		vec[0] *= 2.0f;
222 		vec[1] *= 2.0f;
223     amp*=0.5f;
224 	}
225 
226 
227 	return result;
228 }
229 
230 
231 
Perlin(int octaves,float freq,float amp,int seed)232 Perlin::Perlin(int octaves,float freq,float amp,int seed)
233 {
234   mOctaves = octaves;
235   mFrequency = freq;
236   mAmplitude = amp;
237   mSeed = seed;
238   mStart = true;
239 }
240 
~Perlin()241 Perlin::~Perlin()
242 {
243   srand(time(NULL));
244 }