11import func Glibc. sin
22import func Glibc. cos
33
4- fileprivate let SQUISH_2D : Double = 0.5 * ( 1 / 3 . squareRoot ( ) - 1 )
5- fileprivate let STRETCH_2D : Double = 0.5 * ( 3 . squareRoot ( ) - 1 )
4+ fileprivate
5+ enum Const
6+ {
7+ fileprivate static
8+ let SQUISH_2D : Double = 0.5 * ( 1 / 3 . squareRoot ( ) - 1 ) ,
9+ STRETCH_2D : Double = 0.5 * ( 3 . squareRoot ( ) - 1 )
10+
11+ // each gradient appears four times to mitigate hashing biases
12+ fileprivate static
13+ let GRADIENTS_2D : [ Math . DoubleV2 ] =
14+ [
15+ ( 1 , 0 ) , ( 0 , 1 ) , ( - 1 , 0 ) , ( 0 , - 1 ) ,
16+ ( 0.7 , 0.7 ) , ( - 0.7 , 0.7 ) , ( - 0.7 , - 0.7 ) , ( 0.7 , - 0.7 ) ,
17+
18+ ( 0.7 , - 0.7 ) ,
19+ ( 1 , 0 ) , ( 0 , 1 ) , ( - 1 , 0 ) , ( 0 , - 1 ) ,
20+ ( 0.7 , 0.7 ) , ( - 0.7 , 0.7 ) , ( - 0.7 , - 0.7 ) ,
21+
22+ ( - 0.7 , - 0.7 ) , ( 0.7 , - 0.7 ) ,
23+ ( 1 , 0 ) , ( 0 , 1 ) , ( - 1 , 0 ) , ( 0 , - 1 ) ,
24+ ( 0.7 , 0.7 ) , ( - 0.7 , 0.7 ) ,
25+
26+ ( - 0.7 , 0.7 ) , ( - 0.7 , - 0.7 ) , ( 0.7 , - 0.7 ) ,
27+ ( 1 , 0 ) , ( 0 , 1 ) , ( - 1 , 0 ) , ( 0 , - 1 ) ,
28+ ( 0.7 , 0.7 )
29+ ]
30+
31+ fileprivate static
32+ let GRADIENTS_3D : [ Math . DoubleV3 ] =
33+ [
34+ ( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 1 , - 1 , 0 ) , ( - 1 , - 1 , 0 ) ,
35+ ( 1 , 0 , 1 ) , ( - 1 , 0 , 1 ) , ( 1 , 0 , - 1 ) , ( - 1 , 0 , - 1 ) ,
36+ ( 0 , 1 , 1 ) , ( 0 , - 1 , 1 ) , ( 0 , 1 , - 1 ) , ( 0 , - 1 , - 1 ) ,
37+ ( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 0 , - 1 , 1 ) , ( 0 , - 1 , - 1 ) ,
38+
39+ ( 0 , - 1 , - 1 ) ,
40+ ( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 1 , - 1 , 0 ) , ( - 1 , - 1 , 0 ) ,
41+ ( 1 , 0 , 1 ) , ( - 1 , 0 , 1 ) , ( 1 , 0 , - 1 ) , ( - 1 , 0 , - 1 ) ,
42+ ( 0 , 1 , 1 ) , ( 0 , - 1 , 1 ) , ( 0 , 1 , - 1 ) , ( 0 , - 1 , - 1 ) ,
43+ ( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 0 , - 1 , 1 )
44+ ]
45+ }
646
747fileprivate
848protocol GradientNoise2D : Noise
949{
1050 var permutation_table : PermutationTable { get }
1151
12- static var gradient_table16 : [ Math . DoubleV2 ] { get }
52+ static var gradient_table32 : [ Math . DoubleV2 ] { get }
1353 static var radius : Double { get }
54+
55+
1456}
1557
1658fileprivate
@@ -21,7 +63,7 @@ extension GradientNoise2D
2163 let dr : Double = Self . radius - Math. dot ( offset, offset)
2264 if dr > 0
2365 {
24- let gradient : Math . DoubleV2 = Self . gradient_table16 [ self . permutation_table. hash ( point) & 15 ] ,
66+ let gradient : Math . DoubleV2 = Self . gradient_table32 [ self . permutation_table. hash ( point) & 31 ] ,
2567 drdr : Double = dr * dr
2668 return drdr * drdr * Math. dot ( gradient, offset)
2769 }
@@ -36,14 +78,7 @@ public
3678struct SimplexNoise2D : GradientNoise2D
3779{
3880 fileprivate static
39- let gradient_table16 : [ Math . DoubleV2 ] =
40- [
41- ( - 1 , - 1 ) , ( 1 , 0 ) , ( - 1 , 0 ) , ( 1 , 1 ) ,
42- ( - 1 , 1 ) , ( 0 , - 1 ) , ( 0 , 1 ) , ( 1 , - 1 ) ,
43-
44- ( - 1 , - 1 ) , ( 1 , 0 ) , ( - 1 , 0 ) , ( 1 , 1 ) ,
45- ( - 1 , 1 ) , ( 0 , - 1 ) , ( 0 , 1 ) , ( 1 , - 1 )
46- ]
81+ let gradient_table32 : [ Math . DoubleV2 ] = Const . GRADIENTS_2D
4782
4883 fileprivate static
4984 let radius : Double = 2
@@ -58,7 +93,7 @@ struct SimplexNoise2D:GradientNoise2D
5893 public
5994 init ( amplitude: Double , frequency: Double , seed: Int = 0 )
6095 {
61- self . amplitude = 0.096 * amplitude
96+ self . amplitude = 0.1322 * amplitude
6297 self . frequency = frequency
6398 self . permutation_table = PermutationTable ( seed: seed)
6499 }
@@ -69,7 +104,7 @@ struct SimplexNoise2D:GradientNoise2D
69104 let sample : Math . DoubleV2 = ( x * self . frequency, y * self . frequency)
70105 // transform our coordinate system so that the *simplex* (x, y) forms a
71106 // rectangular grid (u, v)
72- let squish_offset : Double = ( sample. x + sample. y) * SQUISH_2D,
107+ let squish_offset : Double = ( sample. x + sample. y) * Const . SQUISH_2D,
73108 sample_uv : Math . DoubleV2 = ( sample. x + squish_offset, sample. y + squish_offset)
74109
75110 // get integral (u, v) coordinates of the rhombus and get position inside
@@ -99,7 +134,7 @@ struct SimplexNoise2D:GradientNoise2D
99134 // do the same in the original (x, y) coordinate space
100135
101136 // stretch back to get (x, y) coordinates of rhombus origin
102- let stretch_offset : Double = Double ( bin. a + bin. b) * STRETCH_2D,
137+ let stretch_offset : Double = Double ( bin. a + bin. b) * Const . STRETCH_2D,
103138 origin : Math . DoubleV2 = ( Double ( bin. a) + stretch_offset, Double ( bin. b) + stretch_offset)
104139
105140 // get relative position inside the rhombus relative to (xb, xb)
@@ -114,27 +149,27 @@ struct SimplexNoise2D:GradientNoise2D
114149 }
115150
116151 // contribution from (1, 0)
117- _inspect ( point_offset: ( 1 , 0 ) , sample_offset: ( 1 + STRETCH_2D, STRETCH_2D) )
152+ _inspect ( point_offset: ( 1 , 0 ) , sample_offset: ( 1 + Const . STRETCH_2D, Const . STRETCH_2D) )
118153
119154 // contribution from (0, 1)
120- _inspect ( point_offset: ( 0 , 1 ) , sample_offset: ( STRETCH_2D, 1 + STRETCH_2D) )
155+ _inspect ( point_offset: ( 0 , 1 ) , sample_offset: ( Const . STRETCH_2D, 1 + Const . STRETCH_2D) )
121156
122157 // decide which triangle we are in
123158 let uv_sum : Double = sample_uv_rel. x + sample_uv_rel. y
124159 if ( uv_sum > 1 ) // we are to the bottom-right of the diagonal line (du = 1 - dv)
125160 {
126- _inspect ( point_offset: ( 1 , 1 ) , sample_offset: ( 1 + 2 * STRETCH_2D, 1 + 2 * STRETCH_2D) )
161+ _inspect ( point_offset: ( 1 , 1 ) , sample_offset: ( 1 + 2 * Const . STRETCH_2D, 1 + 2 * Const . STRETCH_2D) )
127162
128163 let center_dist : Double = 2 - uv_sum
129164 if center_dist < sample_uv_rel. x || center_dist < sample_uv_rel. y
130165 {
131166 if sample_uv_rel. x > sample_uv_rel. y
132167 {
133- _inspect ( point_offset: ( 2 , 0 ) , sample_offset: ( 2 + 2 * STRETCH_2D, 2 * STRETCH_2D) )
168+ _inspect ( point_offset: ( 2 , 0 ) , sample_offset: ( 2 + 2 * Const . STRETCH_2D, 2 * Const . STRETCH_2D) )
134169 }
135170 else
136171 {
137- _inspect ( point_offset: ( 0 , 2 ) , sample_offset: ( 2 * STRETCH_2D, 2 + 2 * STRETCH_2D) )
172+ _inspect ( point_offset: ( 0 , 2 ) , sample_offset: ( 2 * Const . STRETCH_2D, 2 + 2 * Const . STRETCH_2D) )
138173 }
139174 }
140175 else
@@ -160,7 +195,7 @@ struct SimplexNoise2D:GradientNoise2D
160195 }
161196 else
162197 {
163- _inspect ( point_offset: ( 1 , 1 ) , sample_offset: ( 1 + 2 * STRETCH_2D, 1 + 2 * STRETCH_2D) )
198+ _inspect ( point_offset: ( 1 , 1 ) , sample_offset: ( 1 + 2 * Const . STRETCH_2D, 1 + 2 * Const . STRETCH_2D) )
164199 }
165200 }
166201
@@ -192,7 +227,7 @@ struct SuperSimplexNoise2D:GradientNoise2D
192227 @inline ( __always)
193228 func _lattice_point( at point: Math . IntV2 ) -> ( Math . IntV2 , Math . DoubleV2 )
194229 {
195- let stretch_offset : Double = Double ( point. a + point. b) * SQUISH_2D
230+ let stretch_offset : Double = Double ( point. a + point. b) * Const . SQUISH_2D
196231 return ( point, ( Double ( point. a) + stretch_offset, Double ( point. b) + stretch_offset) )
197232 }
198233
@@ -212,20 +247,7 @@ struct SuperSimplexNoise2D:GradientNoise2D
212247 } ( )
213248
214249 static
215- let gradient_table16 : [ Math . DoubleV2 ] =
216- {
217- var gradients : [ Math . DoubleV2 ] = [ ]
218- gradients. reserveCapacity ( 16 )
219-
220- let dθ : Double = 2 * Double. pi / Double( 16 )
221- for i in 0 ..< 16
222- {
223- let θ : Double = Double ( i) * dθ
224- gradients. append ( ( cos ( θ) , sin ( θ) ) )
225- }
226-
227- return gradients
228- } ( )
250+ let gradient_table32 : [ Math . DoubleV2 ] = Const . GRADIENTS_2D
229251
230252 static
231253 let radius : Double = 2 / 3
@@ -239,7 +261,7 @@ struct SuperSimplexNoise2D:GradientNoise2D
239261 public
240262 init ( amplitude: Double , frequency: Double , seed: Int = 0 )
241263 {
242- self . amplitude = 18 * amplitude
264+ self . amplitude = 18.5 * amplitude
243265 self . frequency = frequency
244266 self . permutation_table = PermutationTable ( seed: seed)
245267 }
@@ -249,7 +271,7 @@ struct SuperSimplexNoise2D:GradientNoise2D
249271 {
250272 let sample : Math . DoubleV2 = ( x * self . frequency, y * self . frequency)
251273 // transform our (x, y) coordinate to (u, v) space
252- let stretch_offset : Double = ( sample. x + sample. y) * STRETCH_2D,
274+ let stretch_offset : Double = ( sample. x + sample. y) * Const . STRETCH_2D,
253275 sample_uv : Math . DoubleV2 = ( sample. x + stretch_offset, sample. y + stretch_offset)
254276
255277 // (0, 0) ----- (1, 0)
@@ -358,7 +380,7 @@ struct SuperSimplexNoise2D:GradientNoise2D
358380 */
359381
360382 // get the relative offset from (0, 0)
361- let squish_offset : Double = ( sample_uv_rel. x + sample_uv_rel. y) * SQUISH_2D,
383+ let squish_offset : Double = ( sample_uv_rel. x + sample_uv_rel. y) * Const . SQUISH_2D,
362384 sample_rel : Math . DoubleV2 = ( sample_uv_rel. x + squish_offset, sample_uv_rel. y + squish_offset)
363385
364386 var Σ : Double = 0
@@ -408,13 +430,7 @@ struct SuperSimplexNoise3D:Noise
408430 } ( )
409431
410432 private static
411- let gradient_table16 : [ Math . DoubleV3 ] =
412- [
413- ( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 1 , - 1 , 0 ) , ( - 1 , - 1 , 0 ) ,
414- ( 1 , 0 , 1 ) , ( - 1 , 0 , 1 ) , ( 1 , 0 , - 1 ) , ( - 1 , 0 , - 1 ) ,
415- ( 0 , 1 , 1 ) , ( 0 , - 1 , 1 ) , ( 0 , 1 , - 1 ) , ( 0 , - 1 , - 1 ) ,
416- ( 1 , 1 , 0 ) , ( - 1 , 1 , 0 ) , ( 0 , - 1 , 1 ) , ( 0 , - 1 , - 1 )
417- ]
433+ let gradient_table32 : [ Math . DoubleV3 ] = Const . GRADIENTS_3D
418434
419435 private
420436 let permutation_table : PermutationTable
@@ -437,7 +453,7 @@ struct SuperSimplexNoise3D:Noise
437453 let dr : Double = 0.75 - Math. dot ( offset, offset)
438454 if dr > 0
439455 {
440- let gradient : Math . DoubleV3 = SuperSimplexNoise3D . gradient_table16 [ self . permutation_table. hash ( point) & 15 ] ,
456+ let gradient : Math . DoubleV3 = SuperSimplexNoise3D . gradient_table32 [ self . permutation_table. hash ( point) & 31 ] ,
441457 drdr : Double = dr * dr
442458 return drdr * drdr * Math. dot ( gradient, offset)
443459 }
0 commit comments