#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
use rand::prelude::*;
use rand::seq::SliceRandom;
use rand_pcg::Pcg64;
static PERMUTATION: [u16; 512] = [
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69,
142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219,
203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175,
74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230,
220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76,
132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173,
186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206,
59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163,
70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232,
178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162,
241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204,
176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141,
128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194,
233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234,
75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174,
20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83,
111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25,
63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188,
159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147,
118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170,
213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253,
19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193,
238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,
181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93,
222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180,
];
const MAX: f32 = 0.855349;
const MIN: f32 = -0.855349;
pub struct NoiseConfig {
pub octaves: i32,
pub x_frequency: f32,
pub y_frequency: f32,
pub amplitude: f32,
pub lacunarity: f32,
pub gain: f32,
pub range: (f32, f32),
pub seed: u64,
pub permutation: [u16; 512],
}
impl NoiseConfig {
pub fn new(
octaves: i32,
x_frequency: f32,
y_frequency: f32,
amplitude: f32,
lacunarity: f32,
gain: f32,
range: (f32, f32),
seed: u64,
) -> Self {
let permutation: [u16; 512] = set_seed(seed);
let result = NoiseConfig {
octaves,
x_frequency,
y_frequency,
amplitude,
lacunarity,
gain,
range,
seed,
permutation,
};
return result;
}
pub fn generate_range(&self, x: f32, y: f32) -> f32 {
let (value, max_value, min_value) = self.fbm(x, y);
return convert_range(max_value, min_value, self.range.0, self.range.1, value);
}
pub fn generate_rangeless(&self, x: f32, y: f32) -> f32 {
return self.fbm(x, y).0;
}
fn fbm(&self, x: f32, y: f32) -> (f32, f32, f32) {
let mut x_frequency: f32 = self.x_frequency;
let mut y_frequency: f32 = self.y_frequency;
let mut amplitude: f32 = self.amplitude;
let mut value: f32 = 0.0;
let mut max_value: f32 = 0.0;
let mut min_value: f32 = 0.0;
for i in 0..self.octaves {
value += amplitude * generate(x * x_frequency, y * y_frequency, &self.permutation);
max_value += MAX * amplitude;
min_value += MIN * amplitude;
x_frequency *= self.lacunarity;
y_frequency *= self.lacunarity;
amplitude *= self.gain;
}
return (value, max_value, min_value);
}
pub fn generate_raw_range(&self, x: f32, y: f32) -> f32 {
return convert_range(
MAX,
MIN,
self.range.0,
self.range.1,
generate(x, y, &self.permutation),
);
}
pub fn generate_raw(&self, x: f32, y: f32) -> f32 {
return generate(x, y, &self.permutation);
}
pub fn analyze(&self, amount: i32) {
let mut max: f32 = 0.0;
let mut min: f32 = 0.0;
let mut value: f32 = 0.0;
for x in 0..amount {
for y in 0..amount {
value = self.generate_rangeless(x as f32, y as f32);
if value > max {
max = value;
} else if min > value {
min = value;
}
}
}
println!("Max Value: {}, Min Value: {}", max, min);
}
pub fn output(&self, size: i32, vector: &Vec<char>) {
let mut values: Vec<f32> = vec![];
let mut max: f32 = 0.0;
let mut min: f32 = 0.0;
let mut v: f32 = 0.0;
for x in 0..size {
for y in 0..size {
v = self.generate_rangeless(x as f32, y as f32);
values.push(v);
if v > max {
max = v;
} else if min > v {
min = v;
}
}
}
let dif: f32 = (max + (min * -1.0)) / vector.len() as f32;
let mut graph: Vec<char> = vec![];
for v in 0..values.len() {
for c in 0..vector.len() {
if (values[v] > (min + (dif * c as f32)))
&& ((min + (dif * (c as f32 + 1.0))) > values[v])
{
graph.push(vector[c]);
break;
}
}
}
for h in 0..size - 1 {
for w in 0..size - 1 {
print!("{}", graph[(h + (w * size)) as usize])
}
println!("");
}
}
pub fn output_1d(&self, length: i32, height: i32) {
let mut values: Vec<f32> = vec![];
let mut max: f32 = 0.0;
let mut min: f32 = 0.0;
let mut v: f32 = 0.0;
for i in 0..length {
v = self.generate_rangeless(i as f32, 0.0);
values.push(v);
if v > max {
max = v;
} else if min > v {
min = v;
}
}
let dif: f32 = (max + (min * -1.0)) / height as f32;
let mut graph: Vec<char> = vec![];
for v in 0..values.len() {
for i in 0..height {
if (values[v] > (min + (dif * i as f32)))
&& ((min + (dif * (i as f32 + 1.0))) > values[v])
{
graph.push('*');
} else {
graph.push(' ');
}
}
}
for c in 0..height {
print!("|");
for r in 0..length {
print!("{}", graph[(c + (r * height)) as usize])
}
println!("");
}
print!("+");
for i in 1..length {
print!("-");
}
println!(
"\n Max Value: {}, Min Value: {}, Difference: {}",
max, min, dif
);
}
}
fn set_seed(seed: u64) -> [u16; 512] {
if seed == 0 {
return PERMUTATION;
} else {
let mut permutation = PERMUTATION;
let mut rng = Pcg64::seed_from_u64(seed);
permutation.shuffle(&mut rng);
return permutation;
}
}
fn convert_range(old_max: f32, old_min: f32, new_max: f32, new_min: f32, value: f32) -> f32 {
let scale: f32 = (new_min - new_max) / (old_min - old_max);
return new_max + (value - old_max) * scale;
}
const F2: f32 = 0.366025403;
const G2: f32 = 0.211324865;
pub fn generate(x: f32, y: f32, permutation: &[u16; 512]) -> f32 {
let mut n0: f32 = 0.0;
let mut n1: f32 = 0.0;
let mut n2: f32 = 0.0;
let s = (x + y) * F2;
let xs = x + s;
let ys = y + s;
let i = fast_floor(xs);
let j = fast_floor(ys);
let t: f32 = ((i + j) as f32) * G2;
let x_0 = i as f32 - t;
let y_0 = j as f32 - t;
let x_0 = x - x_0;
let y_0 = y - y_0;
let mut i1: i32 = 0;
let mut j1: i32 = 0;
if x_0 > y_0 {
i1 = 1;
j1 = 0;
} else {
i1 = 0;
j1 = 1;
}
let x1 = x_0 - i1 as f32 + G2;
let y1 = y_0 - j1 as f32 + G2;
let x2 = x_0 - 1.0 + 2.0 * G2;
let y2 = y_0 - 1.0 + 2.0 * G2;
let ii = modulo(i, 256);
let jj = modulo(j, 256);
let mut t0 = 0.5 - x_0 * x_0 - y_0 * y_0;
if t0 < 0.0 {
n0 = 0.0;
} else {
t0 *= t0;
let temp = permutation[jj as usize];
n0 = t0 * t0 * gradient(permutation[(ii + temp as i32) as usize], x_0, y_0);
}
let mut t1 = 0.5 - x1 * x1 - y1 * y1;
if t1 < 0.0 {
n1 = 0.0;
} else {
t1 *= t1;
let temp = permutation[(jj + j1) as usize];
n1 = t1 * t1 * gradient(permutation[(ii + i1 + temp as i32) as usize], x1, y1);
}
let mut t2 = 0.5 - x2 * x2 - y2 * y2;
if t2 < 0.0 {
n2 = 0.0;
} else {
t2 *= t2;
let temp = permutation[(jj + 1) as usize];
n2 = t2 * t2 * gradient(permutation[(ii + 1 + temp as i32) as usize], x2, y2);
}
return 40.0 * (n0 + n1 + n2);
}
fn fast_floor(x: f32) -> i32 {
if x > 0.0 {
return x as i32;
} else {
return (x as i32) - 1;
}
}
fn modulo(x: i32, m: i32) -> i32 {
let a = x % m;
if 0 > a {
return a + m;
} else {
return a;
}
}
fn gradient(hash: u16, x: f32, y: f32) -> f32 {
let h = hash & 7;
let mut u: f32 = if 4 > h { x } else { y };
let v: f32 = if 4 > h { y } else { x };
if h & 1 != 0 {
u *= -1.0;
}
return u + (if h & 2 != 0 { -2.0 * v } else { 2.0 * v });
}