1
1
import func Glibc. sin
2
2
import func Glibc. cos
3
3
4
+ fileprivate
5
+ protocol GradientNoise2D : Noise
6
+ {
7
+ var permutation_table : PermutationTable { get }
8
+
9
+ static var gradient_table16 : [ ( Double , Double ) ] { get }
10
+ static var radius : Double { get }
11
+ }
12
+
13
+ fileprivate
14
+ extension GradientNoise2D
15
+ {
16
+ func gradient( u: Int , v: Int , dx: Double , dy: Double ) -> Double
17
+ {
18
+ let dr : Double = Self . radius - dx*dx - dy*dy
19
+ if dr > 0
20
+ {
21
+ let gradient : ( Double , Double ) = Self . gradient_table16 [ self . permutation_table. hash ( u, v) & 15 ] ,
22
+ drdr : Double = dr * dr
23
+ return drdr * drdr * ( gradient. 0 * dx + gradient. 1 * dy)
24
+ }
25
+ else
26
+ {
27
+ return 0
28
+ }
29
+ }
30
+ }
31
+
4
32
public
5
- struct SuperSimplex2D : GradientNoise2D
33
+ struct SimplexNoise2D : GradientNoise2D
34
+ {
35
+ fileprivate static
36
+ let gradient_table16 : [ ( Double , Double ) ] =
37
+ [
38
+ ( - 1 , - 1 ) , ( 1 , 0 ) , ( - 1 , 0 ) , ( 1 , 1 ) ,
39
+ ( - 1 , 1 ) , ( 0 , - 1 ) , ( 0 , 1 ) , ( 1 , - 1 ) ,
40
+
41
+ ( - 1 , - 1 ) , ( 1 , 0 ) , ( - 1 , 0 ) , ( 1 , 1 ) ,
42
+ ( - 1 , 1 ) , ( 0 , - 1 ) , ( 0 , 1 ) , ( 1 , - 1 )
43
+ ]
44
+
45
+ fileprivate static
46
+ let radius : Double = 2
47
+
48
+ fileprivate
49
+ let permutation_table : PermutationTable
50
+
51
+ private
52
+ let amplitude : Double , // this is not necissaryly the same amplitude passed into the initializer
53
+ frequency : Double
54
+
55
+ public
56
+ init ( amplitude: Double , frequency: Double , seed: Int = 0 )
57
+ {
58
+ self . amplitude = 0.096 * amplitude
59
+ self . frequency = frequency
60
+ self . permutation_table = PermutationTable ( seed: seed)
61
+ }
62
+
63
+ public
64
+ func evaluate( _ x: Double , _ y: Double ) -> Double
65
+ {
66
+ let x : Double = x * self . frequency,
67
+ y : Double = y * self . frequency
68
+ // transform our coordinate system so that the *simplex* (x, y) forms a rectangular grid (u, v)
69
+ let squish_offset : Double = ( x + y) * SQUISH_2D,
70
+ u : Double = x + squish_offset,
71
+ v : Double = y + squish_offset
72
+
73
+ // get integral (u, v) coordinates of the rhombus
74
+ let ub : Int = floor ( u) ,
75
+ vb : Int = floor ( v)
76
+
77
+ // (0, 0) ----- (1, 0)
78
+ // \ A / \
79
+ // \ / \ ← (x, y) coordinates
80
+ // \ / B \
81
+ // (0, 1)-------(1, 1)
82
+
83
+ // (1, -1)
84
+ // / |
85
+ // / D |
86
+ // / |
87
+ // (ub, vb) = (0, 0) --- (1, 0) -- (2, 0)
88
+ // / | / | /
89
+ // / E | A / B | C / ← (u, v) coordinates
90
+ // / | / | /
91
+ // (-1, 1) -- (0, 1) --- (1, 1)
92
+ // | /
93
+ // | F /
94
+ // | /
95
+ // (0, 2)
96
+
97
+ // get relative position inside the rhombus relative to (ub, vb)
98
+ let du0 : Double = u - Double( ub) ,
99
+ dv0 : Double = v - Double( vb)
100
+
101
+ // do the same in the original (x, y) coordinate space
102
+
103
+ // stretch back to get (x, y) coordinates of rhombus origin
104
+ let stretch_offset : Double = Double ( ub + vb) * STRETCH_2D,
105
+ xb : Double = Double ( ub) + stretch_offset,
106
+ yb : Double = Double ( vb) + stretch_offset
107
+
108
+ // get relative position inside the rhombus relative to (xb, xb)
109
+ let dx0 : Double = x - xb,
110
+ dy0 : Double = y - yb
111
+
112
+ var Σ : Double = 0 // the value of the noise function, which we will sum up
113
+
114
+ // contribution from (1, 0)
115
+ Σ += gradient ( u : ub + 1 ,
116
+ v : vb,
117
+ dx: dx0 - 1 - STRETCH_2D,
118
+ dy: dy0 - STRETCH_2D)
119
+
120
+ // contribution from (0, 1)
121
+ Σ += gradient ( u : ub,
122
+ v : vb + 1 ,
123
+ dx: dx0 - STRETCH_2D,
124
+ dy: dy0 - 1 - STRETCH_2D)
125
+
126
+ // decide which triangle we are in
127
+ let uv_sum : Double = du0 + dv0
128
+ if ( uv_sum > 1 ) // we are to the bottom-right of the diagonal line (du = 1 - dv)
129
+ {
130
+ Σ += gradient ( u : ub + 1 ,
131
+ v : vb + 1 ,
132
+ dx: dx0 - 1 - 2 * STRETCH_2D,
133
+ dy: dy0 - 1 - 2 * STRETCH_2D)
134
+
135
+ let center_dist : Double = 2 - uv_sum
136
+ if center_dist < du0 || center_dist < dv0
137
+ {
138
+ if du0 > dv0
139
+ {
140
+ Σ += gradient ( u : ub + 2 ,
141
+ v : vb ,
142
+ dx: dx0 - 2 - 2 * STRETCH_2D,
143
+ dy: dy0 - 2 * STRETCH_2D)
144
+ }
145
+ else
146
+ {
147
+ Σ += gradient ( u : ub ,
148
+ v : vb + 2 ,
149
+ dx: dx0 - 2 * STRETCH_2D,
150
+ dy: dy0 - 2 - 2 * STRETCH_2D)
151
+ }
152
+ }
153
+ else
154
+ {
155
+ Σ += gradient ( u : ub,
156
+ v : vb,
157
+ dx: dx0,
158
+ dy: dy0)
159
+ }
160
+ }
161
+ else
162
+ {
163
+ Σ += gradient ( u : ub,
164
+ v : vb,
165
+ dx: dx0,
166
+ dy: dy0)
167
+
168
+ let center_dist : Double = 1 - uv_sum
169
+ if center_dist > du0 || center_dist > dv0
170
+ {
171
+ if du0 > dv0
172
+ {
173
+ Σ += gradient ( u : ub + 1 ,
174
+ v : vb - 1 ,
175
+ dx: dx0 + 1 ,
176
+ dy: dy0 - 1 )
177
+ }
178
+ else
179
+ {
180
+ Σ += gradient ( u : ub - 1 ,
181
+ v : vb + 1 ,
182
+ dx: dx0 - 1 ,
183
+ dy: dy0 + 1 )
184
+ }
185
+ }
186
+ else
187
+ {
188
+ Σ += gradient ( u : ub + 1 ,
189
+ v : vb + 1 ,
190
+ dx: dx0 - 1 - 2 * STRETCH_2D,
191
+ dy: dy0 - 1 - 2 * STRETCH_2D)
192
+ }
193
+ }
194
+
195
+ return self . amplitude * Σ
196
+ }
197
+
198
+ public
199
+ func evaluate( _ x: Double , _ y: Double , _: Double ) -> Double
200
+ {
201
+ return self . evaluate ( x, y)
202
+ }
203
+
204
+ public
205
+ func evaluate( _ x: Double , _ y: Double , _: Double , _: Double ) -> Double
206
+ {
207
+ return self . evaluate ( x, y)
208
+ }
209
+ }
210
+
211
+ public
212
+ struct SuperSimplexNoise2D : GradientNoise2D
6
213
{
7
214
private
8
215
struct LatticePoint
@@ -213,7 +420,7 @@ struct SuperSimplex2D:GradientNoise2D
213
420
| - |
214
421
| - |
215
422
| - |
216
- u = 2v - 1 | - | u = 2v
423
+ u = 2v - 1 | - | u = 2v
217
424
| - |
218
425
| - |
219
426
(1, 0) -------------- (1, 1)
@@ -241,7 +448,7 @@ struct SuperSimplex2D:GradientNoise2D
241
448
dy0 : Double = dv0 + squish_offset
242
449
243
450
var Σ : Double = 0
244
- for point in SuperSimplex2D . points [ base_vertex_index ..< base_vertex_index + 4 ]
451
+ for point in SuperSimplexNoise2D . points [ base_vertex_index ..< base_vertex_index + 4 ]
245
452
{
246
453
// get the relative offset from *that* particular point
247
454
let dx : Double = dx0 - point. dx,
@@ -265,7 +472,7 @@ struct SuperSimplex2D:GradientNoise2D
265
472
}
266
473
267
474
public
268
- struct SuperSimplex3D : GradientNoise3D
475
+ struct SuperSimplexNoise3D : Noise
269
476
{
270
477
private
271
478
struct LatticePoint
@@ -346,7 +553,7 @@ struct SuperSimplex3D:GradientNoise3D
346
553
return points
347
554
} ( )
348
555
349
- static
556
+ private static
350
557
let gradient_table16 : [ ( Double , Double , Double ) ] =
351
558
[
352
559
( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 1 , - 1 , 0 ) , ( - 1 , - 1 , 0 ) ,
@@ -355,6 +562,7 @@ struct SuperSimplex3D:GradientNoise3D
355
562
( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 0 , - 1 , 1 ) , ( 0 , - 1 , - 1 )
356
563
]
357
564
565
+ private
358
566
let permutation_table : PermutationTable
359
567
360
568
private
@@ -369,6 +577,22 @@ struct SuperSimplex3D:GradientNoise3D
369
577
self . permutation_table = PermutationTable ( seed: seed)
370
578
}
371
579
580
+ private
581
+ func gradient( u: Int , v: Int , w: Int , dx: Double , dy: Double , dz: Double ) -> Double
582
+ {
583
+ let dr : Double = 0.75 - dx*dx - dy*dy - dz*dz
584
+ if dr > 0
585
+ {
586
+ let gradient : ( Double , Double , Double ) = SuperSimplexNoise3D . gradient_table16 [ self . permutation_table. hash ( u, v, w) & 15 ] ,
587
+ drdr : Double = dr * dr
588
+ return drdr * drdr * ( gradient. 0 * dx + gradient. 1 * dy + gradient. 2 * dz)
589
+ }
590
+ else
591
+ {
592
+ return 0
593
+ }
594
+ }
595
+
372
596
public
373
597
func evaluate( _ x: Double , _ y: Double ) -> Double
374
598
{
@@ -424,7 +648,7 @@ struct SuperSimplex3D:GradientNoise3D
424
648
425
649
// sum up the contributions from the two lattices
426
650
var Σ : Double = 0
427
- for point in SuperSimplex3D . points [ base_vertex_index1 ..< base_vertex_index1 + 4 ]
651
+ for point in SuperSimplexNoise3D . points [ base_vertex_index1 ..< base_vertex_index1 + 4 ]
428
652
{
429
653
// get the relative offset from *that* particular point
430
654
let dx : Double = du1 - point. du,
@@ -433,7 +657,7 @@ struct SuperSimplex3D:GradientNoise3D
433
657
Σ += self . gradient ( u: ub1 + point. u, v: vb1 + point. v, w: wb1 + point. w, dx: dx, dy: dy, dz: dz)
434
658
}
435
659
436
- for point in SuperSimplex3D . points [ base_vertex_index2 ..< base_vertex_index2 + 4 ]
660
+ for point in SuperSimplexNoise3D . points [ base_vertex_index2 ..< base_vertex_index2 + 4 ]
437
661
{
438
662
// get the relative offset from *that* particular point
439
663
let dx : Double = du2 - point. du,
0 commit comments