@@ -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(
9263export 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