simple_simplex/
lib.rs

1#![allow(dead_code)]
2#![allow(unused_assignments)]
3#![allow(unused_variables)]
4
5use rand::prelude::*;
6use rand::seq::SliceRandom;
7use rand_pcg::Pcg64;
8
9/// Default Permutation.  The Noise Algorithm uses this permutation/lookup table to decide vector gradients.
10static PERMUTATION: [u16; 512] = [
11    151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69,
12    142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219,
13    203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175,
14    74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230,
15    220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76,
16    132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173,
17    186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206,
18    59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163,
19    70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232,
20    178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162,
21    241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204,
22    176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141,
23    128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194,
24    233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234,
25    75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174,
26    20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83,
27    111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25,
28    63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188,
29    159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147,
30    118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170,
31    213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253,
32    19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193,
33    238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,
34    181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93,
35    222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180,
36];
37
38/// The Maximum Value Possible for Raw generation.
39const MAX: f32 = 0.855349;
40/// The Minimum Value Possible for Raw generation.
41const MIN: f32 = -0.855349;
42
43/// The Noise Configuration
44/// 
45/// The Centerpiece of Simple-Simplex. Once you've created a Noise Configuration, you can start generating values. 
46/// Each variable of the NoiseConfig will affect the outputted value. Call the NoiseConfig::new() constructor to set it up. 
47pub struct NoiseConfig {
48    pub octaves: i32,
49    pub x_frequency: f32,
50    pub y_frequency: f32,
51    pub amplitude: f32,
52    pub lacunarity: f32,
53    pub gain: f32,
54    pub range: (f32, f32),
55    pub seed: u64,
56    pub permutation: [u16; 512],
57}
58
59impl NoiseConfig {
60    /// Creates and new Noise Configuration and Defines FBM Values.
61    /// # Examples:
62    ///```rust,ignore
63    /// 
64    /// use simple_simplex::NoiseConfig;
65    /// 
66    ///     let config = NoiseConfig::new(
67    ///         3, // octaves
68    ///         0.01, // x_freq
69    ///         0.01, // y_freq
70    ///         0.05, // amplitude
71    ///         2.5, // lacunarity
72    ///         0.5, // gain
73    ///         (256.0, 255), // outputted range (max, min)
74    ///         67893402, // Seed
75    ///     );
76    /// ```
77    ///
78    /// For more information on what these values mean, please read the GitHub Documentation.
79    pub fn new(
80        octaves: i32,
81        x_frequency: f32,
82        y_frequency: f32,
83        amplitude: f32,
84        lacunarity: f32,
85        gain: f32,
86        range: (f32, f32),
87        seed: u64,
88    ) -> Self {
89        // Define Permutation.
90        let permutation: [u16; 512] = set_seed(seed);
91        // Create a new noise config, prepare to return it.
92        let result = NoiseConfig {
93            octaves,
94            x_frequency,
95            y_frequency,
96            amplitude,
97            lacunarity,
98            gain,
99            range,
100            seed,
101            permutation,
102        };
103        return result;
104    }
105
106    /// Generates a range of values generated with Simplex Noise, and enhanced with Fractal Brownian Motion.
107    /// Returns a simplex noise value WITH Fractal Brownian Motion (FBM) applied.  This value is also converted into a range.
108    pub fn generate_range(&self, x: f32, y: f32) -> f32 {
109        let (value, max_value, min_value) = self.fbm(x, y);
110        return convert_range(max_value, min_value, self.range.0, self.range.1, value);
111    }
112
113    /// Generates Simplex Noise Values, and then applies Fractal Brownian Motion.
114    /// Returns a Simplex Noise value WITH FBM applied. This is NOT converted into a range.
115    pub fn generate_rangeless(&self, x: f32, y: f32) -> f32 {
116        return self.fbm(x, y).0;
117    }
118
119    /// This method is private, and is not intended for use by an end-user.
120    /// This function is used for applying Fractal Brownian Motion to Simplex Noise Values.
121    fn fbm(&self, x: f32, y: f32) -> (f32, f32, f32) {
122        // Values defined according to Config, but can also be changed.
123        let mut x_frequency: f32 = self.x_frequency;
124        let mut y_frequency: f32 = self.y_frequency;
125        let mut amplitude: f32 = self.amplitude;
126
127        // The Value each octave will be added to.
128        let mut value: f32 = 0.0;
129
130        // The Max value possible given the amplitude and gain.
131        let mut max_value: f32 = 0.0;
132
133        // the min value possible given the amplitude and gain.
134        let mut min_value: f32 = 0.0;
135
136        for i in 0..self.octaves {
137            // Adds Amplitude and generates a noise value.
138            value += amplitude * generate(x * x_frequency, y * y_frequency, &self.permutation);
139
140            // Finds the max value given the gain and amplitude.
141            max_value += MAX * amplitude;
142
143            // Find the min value
144            min_value += MIN * amplitude;
145
146            // Modifys values at a specified rate.
147            x_frequency *= self.lacunarity;
148            y_frequency *= self.lacunarity;
149            amplitude *= self.gain;
150        }
151
152        // Returns a tuple.
153        // value = final product.
154        // max_value, maximum value of the NoiseConfig through this FBM. 
155        // min_value, the minimum value of the NoiseConfig through this FBM. 
156        return (value, max_value, min_value);
157    }
158
159    /// Generates raw simplex values. 
160    /// DOES NOT apply FBM.
161    /// Converts return value to the range specified in the NoiseConfig. 
162    pub fn generate_raw_range(&self, x: f32, y: f32) -> f32 {
163        return convert_range(
164            MAX,
165            MIN,
166            self.range.0,
167            self.range.1,
168            generate(x, y, &self.permutation),
169        );
170    }
171
172    /// generates raw values, with no FBM or range conversion.
173    /// returns a simplex noise value WITHOUT Fractal Brownian Motion and IS NOT converted into the specified range.
174    pub fn generate_raw(&self, x: f32, y: f32) -> f32 {
175        return generate(x, y, &self.permutation);
176    }
177
178    /// Outputs data on a noise configuration.
179    /// This feature is incomplete.  Please suggest more analysis data on Github.
180    pub fn analyze(&self, amount: i32) {
181        let mut max: f32 = 0.0;
182        let mut min: f32 = 0.0;
183        let mut value: f32 = 0.0;
184
185        for x in 0..amount {
186            for y in 0..amount {
187                value = self.generate_rangeless(x as f32, y as f32);
188                if value > max {
189                    max = value;
190                } else if min > value {
191                    min = value;
192                }
193            }
194        }
195
196        println!("Max Value: {}, Min Value: {}", max, min);
197    }
198
199    /// Output generates noise values to terminal.  Width should not be wider than your terminal can handle.
200    ///
201    /// Note: The `range` of the noise config you output must correlate with theh length of the `vector` of characters used.
202    ///
203    /// # Examples:
204    /// ```rust,ignore
205    ///
206    /// use simple_simplex::NoiseConfig;
207    ///
208    /// fn main() {
209    ///     let vector: Vec<char> = vec![' ',' ', ' ', '.', '-', '=', 'z','X', '#'];
210    ///     let config: NoiseConfig = NoiseConfig::new(
211    ///         3, // Octaves
212    ///         0.01, // X-Frequency
213    ///         0.01, // Y-Frequency
214    ///         0.05, // Amplitude
215    ///         2.5, // Lacunarity
216    ///         0.5, // Gain
217    ///         (0.0, (vector.len() - 1) as f32), // range, must be 0, vector.len() -1 when using output.
218    ///         97838586 // seed
219    ///     );
220    ///
221    ///     config.output(150, &vector);
222    /// }
223    /// ```
224    pub fn output(&self, size: i32, vector: &Vec<char>) {
225        // Set up variables
226        let mut values: Vec<f32> = vec![];
227        let mut max: f32 = 0.0;
228        let mut min: f32 = 0.0;
229        let mut v: f32 = 0.0;
230
231        // Generate Values and find max/min
232        for x in 0..size {
233            for y in 0..size {
234                v = self.generate_rangeless(x as f32, y as f32);
235                values.push(v);
236                if v > max {
237                    max = v;
238                } else if min > v {
239                    min = v;
240                }
241            }
242        }
243
244        // Find the difference value, or the space in between
245        let dif: f32 = (max + (min * -1.0)) / vector.len() as f32;
246
247        // initialize noisemap
248        let mut graph: Vec<char> = vec![];
249
250        for v in 0..values.len() {
251            for c in 0..vector.len() {
252                if (values[v] > (min + (dif * c as f32)))
253                    && ((min + (dif * (c as f32 + 1.0))) > values[v])
254                {
255                    graph.push(vector[c]);
256                    break;
257                }
258            }
259        }
260
261        // Output the values.
262        for h in 0..size - 1 {
263            for w in 0..size - 1 {
264                print!("{}", graph[(h + (w * size)) as usize])
265            }
266            println!("");
267        }
268    }
269
270    /// Outputs a noisemap onto Terminal in 1d form.
271    /// The `length` is the width of the outputted map. For starters,
272    /// try 100.
273    ///
274    /// The `Height` is the height of the map. For starters, try `30`.
275    /// # Examples
276    /// ```rust,ignore
277    /// // Create a noise config called `config`
278    ///
279    /// config.output_1d(30, 100);
280    /// ```
281    pub fn output_1d(&self, length: i32, height: i32) {
282        // Set up variables
283        let mut values: Vec<f32> = vec![];
284        let mut max: f32 = 0.0;
285        let mut min: f32 = 0.0;
286        let mut v: f32 = 0.0;
287
288        // Generate values and find max/min
289        for i in 0..length {
290            v = self.generate_rangeless(i as f32, 0.0);
291            values.push(v);
292            if v > max {
293                max = v;
294            } else if min > v {
295                min = v;
296            }
297        }
298
299        // Find the difference, or the space in between.
300        let dif: f32 = (max + (min * -1.0)) / height as f32;
301
302        // create vector to store characters for graph.
303        let mut graph: Vec<char> = vec![];
304
305        // Find out where the '*' should go.
306        for v in 0..values.len() {
307            for i in 0..height {
308                if (values[v] > (min + (dif * i as f32)))
309                    && ((min + (dif * (i as f32 + 1.0))) > values[v])
310                {
311                    graph.push('*');
312                } else {
313                    graph.push(' ');
314                }
315            }
316        }
317
318        // Output graph
319        for c in 0..height {
320            print!("|");
321            for r in 0..length {
322                print!("{}", graph[(c + (r * height)) as usize])
323            }
324            println!("");
325        }
326
327        // tidy things up
328        print!("+");
329        for i in 1..length {
330            print!("-");
331        }
332        // output analysis data.
333        println!(
334            "\n Max Value: {}, Min Value: {}, Difference: {}",
335            max, min, dif
336        );
337
338        //println!("{:?}", graph);
339    }
340}
341
342/// This function is private and is not intended to be used by an end-user.
343/// Scrambles a Noise Configuration's Permutation when it is created.
344/// uses `rand` with `Pcg64` and SliceRandom's shuffle function to shuffle.
345fn set_seed(seed: u64) -> [u16; 512] {
346    if seed == 0 {
347        return PERMUTATION;
348    } else {
349        let mut permutation = PERMUTATION;
350        let mut rng = Pcg64::seed_from_u64(seed);
351        permutation.shuffle(&mut rng);
352        return permutation;
353    }
354}
355
356/// This function is private and is not intended to be used by an end-user.
357/// This function converts a value from one range to another.
358fn convert_range(old_max: f32, old_min: f32, new_max: f32, new_min: f32, value: f32) -> f32 {
359    let scale: f32 = (new_min - new_max) / (old_min - old_max);
360    return new_max + (value - old_max) * scale;
361}
362
363// Constant for `generate`
364const F2: f32 = 0.366025403;
365// Constant for `generate`
366const G2: f32 = 0.211324865;
367
368/// Generate raw simplex noise values
369/// # Examples
370/// ```rust,ignore
371/// use simple_simplex;
372///
373/// let value: f32 = generate(10, 10);
374/// ```
375///
376/// use `generate` to create your own FBM implementations, or just to generate
377/// raw values.
378///
379/// The maximum value this can generate is 0.855349, and the minimum is -0.855349.
380///
381/// To increase or decrease the `scale`, multiply `x` and `y` by a value less than 0.
382pub fn generate(x: f32, y: f32, permutation: &[u16; 512]) -> f32 {
383    let mut n0: f32 = 0.0;
384    let mut n1: f32 = 0.0;
385    let mut n2: f32 = 0.0;
386
387    let s = (x + y) * F2;
388    let xs = x + s;
389    let ys = y + s;
390    let i = fast_floor(xs);
391    let j = fast_floor(ys);
392
393    let t: f32 = ((i + j) as f32) * G2;
394    let x_0 = i as f32 - t;
395    let y_0 = j as f32 - t;
396    let x_0 = x - x_0;
397    let y_0 = y - y_0;
398
399    let mut i1: i32 = 0;
400    let mut j1: i32 = 0;
401    if x_0 > y_0 {
402        i1 = 1;
403        j1 = 0;
404    } else {
405        i1 = 0;
406        j1 = 1;
407    }
408
409    let x1 = x_0 - i1 as f32 + G2;
410    let y1 = y_0 - j1 as f32 + G2;
411    let x2 = x_0 - 1.0 + 2.0 * G2;
412    let y2 = y_0 - 1.0 + 2.0 * G2;
413
414    let ii = modulo(i, 256);
415    let jj = modulo(j, 256);
416
417    let mut t0 = 0.5 - x_0 * x_0 - y_0 * y_0;
418    if t0 < 0.0 {
419        n0 = 0.0;
420    } else {
421        t0 *= t0;
422        let temp = permutation[jj as usize];
423        n0 = t0 * t0 * gradient(permutation[(ii + temp as i32) as usize], x_0, y_0);
424    }
425
426    let mut t1 = 0.5 - x1 * x1 - y1 * y1;
427    if t1 < 0.0 {
428        n1 = 0.0;
429    } else {
430        t1 *= t1;
431        let temp = permutation[(jj + j1) as usize];
432        n1 = t1 * t1 * gradient(permutation[(ii + i1 + temp as i32) as usize], x1, y1);
433    }
434
435    let mut t2 = 0.5 - x2 * x2 - y2 * y2;
436    if t2 < 0.0 {
437        n2 = 0.0;
438    } else {
439        t2 *= t2;
440        let temp = permutation[(jj + 1) as usize];
441        n2 = t2 * t2 * gradient(permutation[(ii + 1 + temp as i32) as usize], x2, y2);
442    }
443
444    return 40.0 * (n0 + n1 + n2);
445}
446
447/// This function is private and is not intended to be used by an end-user
448/// Function for Simplex Noise Algorithm.
449/// Quickly finds the floor of a number faster than std can.
450fn fast_floor(x: f32) -> i32 {
451    if x > 0.0 {
452        return x as i32;
453    } else {
454        return (x as i32) - 1;
455    }
456}
457
458/// This function is private and is not intended to be used by an end-user.
459/// Function for simplex noise algorithm.
460/// Calculates Modulo
461fn modulo(x: i32, m: i32) -> i32 {
462    let a = x % m;
463    if 0 > a {
464        return a + m;
465    } else {
466        return a;
467    }
468}
469
470/// This function is private and is not intended to be used by an end-user.
471/// Function for simplex noise algorithm.
472/// Calculates gradients.
473fn gradient(hash: u16, x: f32, y: f32) -> f32 {
474    let h = hash & 7;
475
476    let mut u: f32 = if 4 > h { x } else { y };
477    let v: f32 = if 4 > h { y } else { x };
478
479    if h & 1 != 0 {
480        u *= -1.0;
481    }
482
483    return u + (if h & 2 != 0 { -2.0 * v } else { 2.0 * v });
484}