@@ -42,10 +42,9 @@ struct CellNoise2D:Noise
42
42
public
43
43
func evaluate( _ x: Double , _ y: Double ) -> Double
44
44
{
45
- let sample : DoubleV2 = ( x * self . frequency, y * self . frequency)
46
-
47
- let bin : IntV2 = ( floor ( sample. x) , floor ( sample. y) ) ,
48
- offset : DoubleV2 = ( sample. x - Double( bin. a) , sample. y - Double( bin. b) )
45
+ let sample : DoubleV2 = ( x * self . frequency , y * self . frequency) ,
46
+ bin : IntV2 = ( floor ( sample. x) , floor ( sample. y) ) ,
47
+ sample_rel : DoubleV2 = ( sample. x - Double( bin. a) , sample. y - Double( bin. b) )
49
48
50
49
// determine kernel
51
50
@@ -80,34 +79,37 @@ struct CellNoise2D:Noise
80
79
// square since it cannot produce a feature point closer than we have already
81
80
// found.
82
81
83
- let quadrant : IntV2 = ( offset . x > 0.5 ? 1 : - 1 , offset . y > 0.5 ? 1 : - 1 ) ,
82
+ let quadrant : IntV2 = ( sample_rel . x > 0.5 ? 1 : - 1 , sample_rel . y > 0.5 ? 1 : - 1 ) ,
84
83
near : IntV2 = ( bin. a + ( quadrant. a + 1 ) >> 1 , bin. b + ( quadrant. b + 1 ) >> 1 ) ,
85
- far : IntV2 = ( near. a - quadrant. a, near. b - quadrant. b)
84
+ far : IntV2 = ( near. a - quadrant. a , near. b - quadrant. b)
86
85
87
- let nearpoint_disp : DoubleV2 = ( abs ( offset . x - Double( ( quadrant. a + 1 ) >> 1 ) ) ,
88
- abs ( offset . y - Double( ( quadrant. b + 1 ) >> 1 ) ) )
86
+ let nearpoint_disp : DoubleV2 = ( abs ( sample_rel . x - Double( ( quadrant. a + 1 ) >> 1 ) ) ,
87
+ abs ( sample_rel . y - Double( ( quadrant. b + 1 ) >> 1 ) ) )
89
88
90
89
var r2 : Double = self . distance ( from: sample, generating_point: near)
91
90
92
91
@inline ( __always)
93
- func test ( generating_point: IntV2 , dx: Double = 0 , dy: Double = 0 )
92
+ func _inspect ( generating_point: IntV2 , dx: Double = 0 , dy: Double = 0 )
94
93
{
95
94
if dx*dx + dy*dy < r2
96
95
{
97
96
r2 = min ( r2, self . distance ( from: sample, generating_point: generating_point) )
98
97
}
99
98
}
100
99
100
+ // Cell group:
101
+ // within r^2 = 0.25
102
+ // cumulative sample coverage = 65.50%
103
+
101
104
// A points
102
- test ( generating_point: ( near. a, far. b) , dy: nearpoint_disp. y - 0.5 )
103
- test ( generating_point: ( far. a, near. b) , dx: nearpoint_disp. x - 0.5 )
105
+ _inspect ( generating_point: ( near. a, far. b) , dy: nearpoint_disp. y - 0.5 )
106
+ _inspect ( generating_point: ( far. a, near. b) , dx: nearpoint_disp. x - 0.5 )
104
107
105
108
// far point
106
- test ( generating_point: far, dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y - 0.5 )
109
+ _inspect ( generating_point: far, dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y - 0.5 )
107
110
108
- // EARLY EXIT: if we have a point within 0.5 units, we don’t have to check
109
- // the outer kernel
110
- if r2 < 0.25
111
+ guard r2 > 0.25
112
+ else
111
113
{
112
114
return self . amplitude * r2
113
115
}
@@ -131,32 +133,37 @@ struct CellNoise2D:Noise
131
133
// inner ----- B ------- C --------+ ← quadrant
132
134
// ↓
133
135
136
+ // Cell group:
137
+ // within r^2 = 1.0
138
+ // cumulative sample coverage = 99.96%
134
139
let inner : IntV2 = ( near. a + quadrant. a, near. b + quadrant. b)
135
140
136
141
// B points
137
- test ( generating_point: ( inner. a, near. b) , dx: nearpoint_disp. x + 0.5 )
138
- test ( generating_point: ( near. a, inner. b) , dy: nearpoint_disp. y + 0.5 )
142
+ _inspect ( generating_point: ( inner. a, near. b) , dx: nearpoint_disp. x + 0.5 )
143
+ _inspect ( generating_point: ( near. a, inner. b) , dy: nearpoint_disp. y + 0.5 )
139
144
140
145
// C points
141
- test ( generating_point: ( inner. a, far. b) , dx: nearpoint_disp. x + 0.5 , dy: nearpoint_disp. y - 0.5 )
142
- test ( generating_point: ( far. a, inner. b) , dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y + 0.5 )
146
+ _inspect ( generating_point: ( inner. a, far. b) , dx: nearpoint_disp. x + 0.5 , dy: nearpoint_disp. y - 0.5 )
147
+ _inspect ( generating_point: ( far. a, inner. b) , dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y + 0.5 )
143
148
144
- // EARLY EXIT: if we have a point within 1 unit, we don’t have to check
145
- // the D points or the E points
146
- if r2 < 1
149
+ guard r2 > 1.0
150
+ else
147
151
{
148
152
return self . amplitude * r2
149
153
}
150
154
155
+ // Cell group:
156
+ // within r^2 = 2.0
157
+ // cumulative sample coverage = 100%
151
158
let outer : IntV2 = ( far. a - quadrant. a, far. b - quadrant. b)
152
159
153
160
// D points
154
- test ( generating_point: ( near. a, outer. b) , dy: nearpoint_disp. y - 1.5 )
155
- test ( generating_point: ( outer. a, near. b) , dx: nearpoint_disp. x - 1.5 )
161
+ _inspect ( generating_point: ( near. a, outer. b) , dy: nearpoint_disp. y - 1.5 )
162
+ _inspect ( generating_point: ( outer. a, near. b) , dx: nearpoint_disp. x - 1.5 )
156
163
157
164
// E points
158
- test ( generating_point: ( far. a, outer. b) , dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y - 1.5 )
159
- test ( generating_point: ( outer. a, far. b) , dx: nearpoint_disp. x - 1.5 , dy: nearpoint_disp. y - 0.5 )
165
+ _inspect ( generating_point: ( far. a, outer. b) , dx: nearpoint_disp. x - 0.5 , dy: nearpoint_disp. y - 1.5 )
166
+ _inspect ( generating_point: ( outer. a, far. b) , dx: nearpoint_disp. x - 1.5 , dy: nearpoint_disp. y - 0.5 )
160
167
161
168
return self . amplitude * r2
162
169
}
@@ -228,8 +235,9 @@ struct CellNoise3D:Noise
228
235
public
229
236
func evaluate( _ x: Double , _ y: Double , _ z: Double ) -> Double
230
237
{
231
- let sample : DoubleV3 = ( x * self . frequency, y * self . frequency, z * self . frequency) ,
232
- bin : IntV3 = ( floor ( sample. x) , floor ( sample. y) , floor ( sample. z) )
238
+ let sample : DoubleV3 = ( x * self . frequency , y * self . frequency , z * self . frequency) ,
239
+ bin : IntV3 = ( floor ( sample. x) , floor ( sample. y) , floor ( sample. z) ) ,
240
+ sample_rel : DoubleV3 = ( sample. x - Double( bin. a) , sample. y - Double( bin. b) , sample. z - Double( bin. c) )
233
241
234
242
// determine kernel
235
243
@@ -242,14 +250,12 @@ struct CellNoise3D:Noise
242
250
// near - quadrant.x ————— near quadrant →
243
251
// ↓
244
252
245
- let quadrant : IntV3 = ( sample. x - Double( bin. a) > 0.5 ? 1 : - 1 ,
246
- sample. y - Double( bin. b) > 0.5 ? 1 : - 1 ,
247
- sample. z - Double( bin. c) > 0.5 ? 1 : - 1 )
253
+ let quadrant : IntV3 = ( sample_rel. x > 0.5 ? 1 : - 1 , sample_rel. y > 0.5 ? 1 : - 1 , sample_rel. z > 0.5 ? 1 : - 1 )
248
254
let near : IntV3 = ( bin. a + ( quadrant. a + 1 ) >> 1 , bin. b + ( quadrant. b + 1 ) >> 1 , bin. c + ( quadrant. c + 1 ) >> 1 )
249
255
250
- let nearpoint_disp : DoubleV3 = ( abs ( offset . x - Double( ( quadrant. a + 1 ) >> 1 ) ) ,
251
- abs ( offset . y - Double( ( quadrant. b + 1 ) >> 1 ) ) ,
252
- abs ( offset . z - Double( ( quadrant. c + 1 ) >> 1 ) ) )
256
+ let nearpoint_disp : DoubleV3 = ( abs ( sample_rel . x - Double( ( quadrant. a + 1 ) >> 1 ) ) ,
257
+ abs ( sample_rel . y - Double( ( quadrant. b + 1 ) >> 1 ) ) ,
258
+ abs ( sample_rel . z - Double( ( quadrant. c + 1 ) >> 1 ) ) )
253
259
254
260
var r2 : Double = self . distance ( from: sample, generating_point: near)
255
261
@@ -258,25 +264,25 @@ struct CellNoise3D:Noise
258
264
{
259
265
// calculate distance from quadrant volume to kernel cell
260
266
var cell_distance2 : Double
261
- if cell_offset . a != 0
267
+ if offset . a != 0
262
268
{ // move by 0.5 towards zero
263
- let dx : Double = nearpoint_disp. x + Double( cell_offset . a) + ( cell_offset . a > 0 ? - 0.5 : 0.5 )
269
+ let dx : Double = nearpoint_disp. x + Double( offset . a) + ( offset . a > 0 ? - 0.5 : 0.5 )
264
270
cell_distance2 = dx*dx
265
271
}
266
272
else
267
273
{
268
274
cell_distance2 = 0
269
275
}
270
276
271
- if cell_offset . b != 0
277
+ if offset . b != 0
272
278
{ // move by 0.5 towards zero
273
- let dy : Double = nearpoint_disp. y + Double( cell_offset . b) + ( cell_offset . b > 0 ? - 0.5 : 0.5 )
279
+ let dy : Double = nearpoint_disp. y + Double( offset . b) + ( offset . b > 0 ? - 0.5 : 0.5 )
274
280
cell_distance2 += dy*dy
275
281
}
276
282
277
- if cell_offset . c != 0
283
+ if offset . c != 0
278
284
{ // move by 0.5 towards zero
279
- let dz : Double = nearpoint_disp. z + Double( cell_offset . c) + ( cell_offset . c > 0 ? - 0.5 : 0.5 )
285
+ let dz : Double = nearpoint_disp. z + Double( offset . c) + ( offset . c > 0 ? - 0.5 : 0.5 )
280
286
cell_distance2 += dz*dz
281
287
}
282
288
@@ -286,9 +292,9 @@ struct CellNoise3D:Noise
286
292
return
287
293
}
288
294
289
- let generating_point : IntV3 = ( near. a + quadrant. a*cell_offset . a,
290
- near. b + quadrant. b*cell_offset . b,
291
- near. c + quadrant. c*cell_offset . c)
295
+ let generating_point : IntV3 = ( near. a + quadrant. a*offset . a,
296
+ near. b + quadrant. b*offset . b,
297
+ near. c + quadrant. c*offset . c)
292
298
r2 = min ( r2, self . distance ( from: sample, generating_point: generating_point) )
293
299
}
294
300
@@ -316,11 +322,11 @@ struct CellNoise3D:Noise
316
322
// Cell group:
317
323
// within r^2 = 0.5
318
324
// cumulative sample coverage = 88.60%
319
- for cell_offset in [ ( 1 , 0 , 0 ) , ( 0 , 1 , 0 ) , ( 0 , 0 , 1 ) ,
320
- ( 0 , - 1 , 1 ) , ( 0 , 1 , - 1 ) , ( 1 , 0 , - 1 ) , ( - 1 , 0 , 1 ) , ( - 1 , 1 , 0 ) , ( 1 , - 1 , 0 ) ,
321
- ( 1 , - 1 , - 1 ) , ( - 1 , 1 , - 1 ) , ( - 1 , - 1 , 1 ) ]
325
+ for offset in [ ( 1 , 0 , 0 ) , ( 0 , 1 , 0 ) , ( 0 , 0 , 1 ) ,
326
+ ( 0 , - 1 , 1 ) , ( 0 , 1 , - 1 ) , ( 1 , 0 , - 1 ) , ( - 1 , 0 , 1 ) , ( - 1 , 1 , 0 ) , ( 1 , - 1 , 0 ) ,
327
+ ( 1 , - 1 , - 1 ) , ( - 1 , 1 , - 1 ) , ( - 1 , - 1 , 1 ) ]
322
328
{
323
- _inspect_cell ( offset: cell_offset )
329
+ _inspect_cell ( offset: offset )
324
330
}
325
331
guard r2 > 0.5
326
332
else
@@ -331,9 +337,9 @@ struct CellNoise3D:Noise
331
337
// Cell group:
332
338
// within r^2 = 0.75
333
339
// cumulative sample coverage = 98.26%
334
- for cell_offset in [ ( 0 , 1 , 1 ) , ( 1 , 0 , 1 ) , ( 1 , 1 , 0 ) , ( - 1 , 1 , 1 ) , ( 1 , - 1 , 1 ) , ( 1 , 1 , - 1 ) ]
340
+ for offset in [ ( 0 , 1 , 1 ) , ( 1 , 0 , 1 ) , ( 1 , 1 , 0 ) , ( - 1 , 1 , 1 ) , ( 1 , - 1 , 1 ) , ( 1 , 1 , - 1 ) ]
335
341
{
336
- _inspect_cell ( offset: cell_offset )
342
+ _inspect_cell ( offset: offset )
337
343
}
338
344
guard r2 > 0.75
339
345
else
@@ -354,11 +360,11 @@ struct CellNoise3D:Noise
354
360
// Cell group:
355
361
// within r^2 = 1.25
356
362
// cumulative sample coverage > 99.99%
357
- for cell_offset in [ ( - 2 , 0 , 0 ) , ( 0 , - 2 , 0 ) , ( 0 , 0 , - 2 ) ,
358
- ( 0 , - 2 , - 1 ) , ( 0 , - 1 , - 2 ) , ( - 2 , 0 , - 1 ) , ( - 1 , 0 , - 2 ) , ( - 2 , - 1 , 0 ) , ( - 1 , - 2 , 0 ) ,
359
- ( - 2 , - 1 , - 1 ) , ( - 1 , - 2 , - 1 ) , ( - 1 , - 1 , - 2 ) ]
363
+ for offset in [ ( - 2 , 0 , 0 ) , ( 0 , - 2 , 0 ) , ( 0 , 0 , - 2 ) ,
364
+ ( 0 , - 2 , - 1 ) , ( 0 , - 1 , - 2 ) , ( - 2 , 0 , - 1 ) , ( - 1 , 0 , - 2 ) , ( - 2 , - 1 , 0 ) , ( - 1 , - 2 , 0 ) ,
365
+ ( - 2 , - 1 , - 1 ) , ( - 1 , - 2 , - 1 ) , ( - 1 , - 1 , - 2 ) ]
360
366
{
361
- _inspect_cell ( offset: cell_offset )
367
+ _inspect_cell ( offset: offset )
362
368
}
363
369
guard r2 > 1.25
364
370
else
@@ -369,10 +375,10 @@ struct CellNoise3D:Noise
369
375
// Cell group:
370
376
// within r^2 = 1.5
371
377
// cumulative sample coverage > 99.99%
372
- for cell_offset in [ ( 0 , 1 , - 2 ) , ( 0 , - 2 , 1 ) , ( 1 , 0 , - 2 ) , ( - 2 , 0 , 1 ) , ( 1 , - 2 , 0 ) , ( - 2 , 1 , 0 ) ,
373
- ( - 2 , 1 , - 1 ) , ( - 2 , - 1 , 1 ) , ( 1 , - 2 , - 1 ) , ( - 1 , - 2 , 1 ) , ( 1 , - 1 , - 2 ) , ( - 1 , 1 , - 2 ) ]
378
+ for offset in [ ( 0 , 1 , - 2 ) , ( 0 , - 2 , 1 ) , ( 1 , 0 , - 2 ) , ( - 2 , 0 , 1 ) , ( 1 , - 2 , 0 ) , ( - 2 , 1 , 0 ) ,
379
+ ( - 2 , 1 , - 1 ) , ( - 2 , - 1 , 1 ) , ( 1 , - 2 , - 1 ) , ( - 1 , - 2 , 1 ) , ( 1 , - 1 , - 2 ) , ( - 1 , 1 , - 2 ) ]
374
380
{
375
- _inspect_cell ( offset: cell_offset )
381
+ _inspect_cell ( offset: offset )
376
382
}
377
383
guard r2 > 1.5
378
384
else
@@ -395,9 +401,9 @@ struct CellNoise3D:Noise
395
401
// Cell group:
396
402
// within r^2 = 2.25
397
403
// cumulative sample coverage > 99.99%
398
- for cell_offset in [ ( 0 , - 2 , - 2 ) , ( - 2 , 0 , - 2 ) , ( - 2 , - 2 , 0 ) , ( - 1 , - 2 , - 2 ) , ( - 2 , - 1 , - 2 ) , ( - 2 , - 2 , - 1 ) ]
404
+ for offset in [ ( 0 , - 2 , - 2 ) , ( - 2 , 0 , - 2 ) , ( - 2 , - 2 , 0 ) , ( - 1 , - 2 , - 2 ) , ( - 2 , - 1 , - 2 ) , ( - 2 , - 2 , - 1 ) ]
399
405
{
400
- _inspect_cell ( offset: cell_offset )
406
+ _inspect_cell ( offset: offset )
401
407
}
402
408
guard r2 > 2.25
403
409
else
@@ -408,11 +414,11 @@ struct CellNoise3D:Noise
408
414
// Cell group:
409
415
// within r^2 = 2.5
410
416
// cumulative sample coverage > 99.99%
411
- for cell_offset in [ ( 2 , 0 , 0 ) , ( 0 , 2 , 0 ) , ( 0 , 0 , 2 ) ,
412
- ( 0 , - 1 , 2 ) , ( 0 , 2 , - 1 ) , ( - 1 , 0 , 2 ) , ( 2 , 0 , - 1 ) , ( - 1 , 2 , 0 ) , ( 2 , - 1 , 0 ) ,
413
- ( 1 , - 2 , - 2 ) , ( 2 , - 1 , - 1 ) , ( - 2 , - 2 , 1 ) , ( - 1 , - 1 , 2 ) , ( - 2 , 1 , - 2 ) , ( - 1 , 2 , - 1 ) ]
417
+ for offset in [ ( 2 , 0 , 0 ) , ( 0 , 2 , 0 ) , ( 0 , 0 , 2 ) ,
418
+ ( 0 , - 1 , 2 ) , ( 0 , 2 , - 1 ) , ( - 1 , 0 , 2 ) , ( 2 , 0 , - 1 ) , ( - 1 , 2 , 0 ) , ( 2 , - 1 , 0 ) ,
419
+ ( 1 , - 2 , - 2 ) , ( 2 , - 1 , - 1 ) , ( - 2 , - 2 , 1 ) , ( - 1 , - 1 , 2 ) , ( - 2 , 1 , - 2 ) , ( - 1 , 2 , - 1 ) ]
414
420
{
415
- _inspect_cell ( offset: cell_offset )
421
+ _inspect_cell ( offset: offset )
416
422
}
417
423
guard r2 > 2.5
418
424
else
@@ -423,10 +429,10 @@ struct CellNoise3D:Noise
423
429
// Cell group:
424
430
// within r^2 = 2.75
425
431
// cumulative sample coverage > 99.99%
426
- for cell_offset in [ ( 0 , 1 , 2 ) , ( 0 , 2 , 1 ) , ( 1 , 0 , 2 ) , ( 2 , 0 , 1 ) , ( 1 , 2 , 0 ) , ( 2 , 1 , 0 ) ,
427
- ( 2 , 1 , - 1 ) , ( 2 , - 1 , 1 ) , ( 1 , 2 , - 1 ) , ( - 1 , 2 , 1 ) , ( 1 , - 1 , 2 ) , ( - 1 , 1 , 2 ) ]
432
+ for offset in [ ( 0 , 1 , 2 ) , ( 0 , 2 , 1 ) , ( 1 , 0 , 2 ) , ( 2 , 0 , 1 ) , ( 1 , 2 , 0 ) , ( 2 , 1 , 0 ) ,
433
+ ( 2 , 1 , - 1 ) , ( 2 , - 1 , 1 ) , ( 1 , 2 , - 1 ) , ( - 1 , 2 , 1 ) , ( 1 , - 1 , 2 ) , ( - 1 , 1 , 2 ) ]
428
434
{
429
- _inspect_cell ( offset: cell_offset )
435
+ _inspect_cell ( offset: offset )
430
436
}
431
437
guard r2 > 2.75
432
438
else
@@ -437,9 +443,9 @@ struct CellNoise3D:Noise
437
443
// Cell group:
438
444
// within r^2 = 3.0
439
445
// cumulative sample coverage = 100%
440
- for cell_offset in [ ( 2 , 1 , 1 ) , ( 1 , 2 , 1 ) , ( 1 , 1 , 2 ) ]
446
+ for offset in [ ( 2 , 1 , 1 ) , ( 1 , 2 , 1 ) , ( 1 , 1 , 2 ) ]
441
447
{
442
- _inspect_cell ( offset: cell_offset )
448
+ _inspect_cell ( offset: offset )
443
449
}
444
450
return self . amplitude * r2
445
451
}
0 commit comments