Skip to content

Commit 7ed2d65

Browse files
committed
implement get*NoiseValue functions
Not yet fully implemented to the point of being able to merge in. will need to update documentation and update tests
1 parent 12bc7f8 commit 7ed2d65

File tree

1 file changed

+129
-63
lines changed

1 file changed

+129
-63
lines changed

src/mod.ts

Lines changed: 129 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,15 @@ export function makeCuboid(
2828
height: number,
2929
depth: number,
3030
noise3: Noise3Fn,
31-
{
32-
amplitude = defaultAmplitude,
33-
frequency = defaultFrequency,
34-
octaves = defaultOctaves,
35-
persistence = defaultPersistence,
36-
scale,
37-
}: Partial<Options> = {},
31+
options: Options,
3832
): number[][][] {
3933
const field: number[][][] = new Array(width);
4034
for (let x = 0; x < width; x++) {
4135
field[x] = new Array(height);
4236
for (let y = 0; y < height; y++) {
4337
field[x][y] = new Array(depth);
4438
for (let z = 0; z < depth; z++) {
45-
let value = 0.0;
46-
for (let octave = 0; octave < octaves; octave++) {
47-
const freq = frequency * Math.pow(2, octave);
48-
value += noise3(x * freq, y * freq, z * freq) *
49-
(amplitude * Math.pow(persistence, octave));
50-
}
51-
field[x][y][z] = value / (2 - 1 / Math.pow(2, octaves - 1));
52-
if (scale) field[x][y][z] = scale(field[x][y][z]);
39+
field[x][y][z] = getCuboidNoiseValue(noise3, options, x, y, z);
5340
}
5441
}
5542
}
@@ -60,30 +47,14 @@ export function makeCylinderSurface(
6047
circumference: number,
6148
height: number,
6249
noise3: Noise3Fn,
63-
{
64-
amplitude = defaultAmplitude,
65-
frequency = defaultFrequency,
66-
octaves = defaultOctaves,
67-
persistence = defaultPersistence,
68-
scale,
69-
}: Partial<Options> = {},
50+
options: Options,
7051
): number[][] {
71-
const radius = circumference / TWO_PI;
52+
const radius = getCircleRadius(circumference);
7253
const field: number[][] = new Array(circumference);
7354
for (let x = 0; x < circumference; x++) {
7455
field[x] = new Array(height);
7556
for (let y = 0; y < height; y++) {
76-
let value = 0.0;
77-
for (let octave = 0; octave < octaves; octave++) {
78-
const freq = frequency * Math.pow(2, octave);
79-
const nx = x / circumference;
80-
const rdx = nx * TWO_PI;
81-
const [a, b] = [radius * Math.sin(rdx), radius * Math.cos(rdx)];
82-
value += noise3(a * freq, b * freq, y * freq) *
83-
(amplitude * Math.pow(persistence, octave));
84-
}
85-
field[x][y] = value / (2 - 1 / Math.pow(2, octaves - 1));
86-
if (scale) field[x][y] = scale(field[x][y]);
57+
field[x][y] = getCylinderSurfaceNoiseValue(noise3, options, circumference, radius, x, y);
8758
}
8859
}
8960
return field;
@@ -92,23 +63,11 @@ export function makeCylinderSurface(
9263
export function makeLine(
9364
length: number,
9465
noise1: Noise1Fn,
95-
{
96-
amplitude = defaultAmplitude,
97-
frequency = defaultFrequency,
98-
octaves = defaultOctaves,
99-
persistence = defaultPersistence,
100-
scale,
101-
}: Partial<Options> = {},
66+
options: Options,
10267
): number[] {
10368
const field: number[] = new Array(length);
10469
for (let x = 0; x < length; x++) {
105-
let value = 0.0;
106-
for (let octave = 0; octave < octaves; octave++) {
107-
const freq = frequency * Math.pow(2, octaves);
108-
value += noise1(x * freq) * (amplitude * Math.pow(persistence, octave));
109-
}
110-
field[x] = value / (2 - 1 / Math.pow(2, octaves - 1));
111-
if (scale) field[x] = scale(field[x]);
70+
field[x] = getLineNoiseValue(noise1, options, x);
11271
}
11372
return field;
11473
}
@@ -117,26 +76,13 @@ export function makeRectangle(
11776
width: number,
11877
height: number,
11978
noise2: Noise2Fn,
120-
{
121-
amplitude = defaultAmplitude,
122-
frequency = defaultFrequency,
123-
octaves = defaultOctaves,
124-
persistence = defaultPersistence,
125-
scale,
126-
}: Partial<Options> = {},
79+
options: Options,
12780
): number[][] {
12881
const field: number[][] = new Array(width);
12982
for (let x = 0; x < width; x++) {
13083
field[x] = new Array(height);
13184
for (let y = 0; y < height; y++) {
132-
let value = 0.0;
133-
for (let octave = 0; octave < octaves; octave++) {
134-
const freq = frequency * Math.pow(2, octave);
135-
value += noise2(x * freq, y * freq) *
136-
(amplitude * Math.pow(persistence, octave));
137-
}
138-
field[x][y] = value / (2 - 1 / Math.pow(2, octaves - 1));
139-
if (scale) field[x][y] = scale(field[x][y]);
85+
field[x][y] = getRectangleNoiseValue(noise2, options, x, y);
14086
}
14187
}
14288
return field;
@@ -176,3 +122,123 @@ export function makeSphereSurface(
176122
}
177123
return field;
178124
}
125+
126+
export function fractalNoiseOptions({
127+
amplitude = defaultAmplitude,
128+
frequency = defaultFrequency,
129+
octaves = defaultOctaves,
130+
persistence = defaultPersistence,
131+
scale,
132+
}: Partial<Options> = {}): Options {
133+
return { amplitude, frequency, octaves, persistence, scale };
134+
}
135+
136+
export function getCircleRadius(
137+
circumference: number,
138+
): number {
139+
return circumference / TWO_PI;
140+
}
141+
142+
export function getCuboidNoiseValue(
143+
noise3: Noise3Fn,
144+
options: Options,
145+
x: number,
146+
y: number,
147+
z: number,
148+
): number {
149+
let value = 0.0;
150+
for (let octave = 0; octave < options.octaves; octave++) {
151+
const freq = options.frequency * Math.pow(2, octave);
152+
value += noise3(x * freq, y * freq, z * freq) *
153+
(options.amplitude * Math.pow(options.persistence, octave));
154+
}
155+
const result = normalizeFractalNoiseValue(options, value);
156+
if (options.scale) return options.scale(result);
157+
return result;
158+
}
159+
160+
export function getCylinderSurfaceNoiseValue(
161+
noise3: Noise3Fn,
162+
options: Options,
163+
circumference: number,
164+
radius: number,
165+
x: number,
166+
y: number,
167+
): number {
168+
let value = 0.0;
169+
for (let octave = 0; octave < options.octaves; octave++) {
170+
const freq = options.frequency * Math.pow(2, octave);
171+
const nx = x / circumference;
172+
const rdx = nx * TWO_PI;
173+
const [a, b] = [radius * Math.sin(rdx), radius * Math.cos(rdx)];
174+
value += noise3(a * freq, b * freq, y * freq) *
175+
(options.amplitude * Math.pow(options.persistence, octave));
176+
}
177+
const result = normalizeFractalNoiseValue(options, value);
178+
if (options.scale) return options.scale(result);
179+
return result;
180+
}
181+
182+
export function getLineNoiseValue(
183+
noise1: Noise1Fn,
184+
options: Options,
185+
x: number,
186+
): number {
187+
let value = 0.0;
188+
for (let octave = 0; octave < options.octaves; octave++) {
189+
const freq = options.frequency * Math.pow(2, octave);
190+
value += noise1(x * freq) * (options.amplitude * Math.pow(options.persistence, octave));
191+
}
192+
const result = normalizeFractalNoiseValue(options, value);
193+
if (options.scale) return options.scale(result);
194+
return result;
195+
}
196+
197+
export function getRectangleNoiseValue(
198+
noise2: Noise2Fn,
199+
options: Options,
200+
x: number,
201+
y: number,
202+
): number {
203+
let value = 0.0;
204+
for (let octave = 0; octave < options.octaves; octave++) {
205+
const freq = options.frequency * Math.pow(2, octave);
206+
value += noise2(x * freq, y * freq) * (options.amplitude * Math.pow(options.persistence, octave));
207+
}
208+
const result = normalizeFractalNoiseValue(options, value);
209+
if (options.scale) return options.scale(result);
210+
return result;
211+
}
212+
213+
export function getSphereSurfaceNoiseValue(
214+
noise3: Noise3Fn,
215+
options: Options,
216+
circumference: number,
217+
circumferenceSemi: number,
218+
x: number,
219+
y: number,
220+
): number {
221+
const [nx, ny] = [x / circumference, y / circumferenceSemi];
222+
const [rdx, rdy] = [nx * TWO_PI, ny * Math.PI];
223+
const sinY = Math.sin(rdy + Math.PI);
224+
const a = TWO_PI * Math.sin(rdx) * sinY;
225+
const b = TWO_PI * Math.cos(rdx) * sinY;
226+
const d = TWO_PI * Math.cos(rdy);
227+
let value = 0.0;
228+
for (let octave = 0; octave < options.octaves; octave++) {
229+
const freq = options.frequency * Math.pow(2, octave);
230+
value += noise3(a * freq, b * freq, d * freq) *
231+
(options.amplitude * Math.pow(options.persistence, octave));
232+
}
233+
const result = normalizeFractalNoiseValue(options, value);
234+
if (options.scale) return options.scale(result);
235+
return result;
236+
}
237+
238+
/**
239+
* Normalize the result so that it's within a similar range regardless of the
240+
* number of octaves.
241+
*/
242+
function normalizeFractalNoiseValue(options: Options, value: number) {
243+
return value / (2 - 1 / Math.pow(2, options.octaves - 1));
244+
}

0 commit comments

Comments
 (0)