noise 0.8.2

Procedural noise generation library.
Documentation
use crate::{
    math::{interpolate, s_curve::quintic::Quintic, vectors::*},
    permutationtable::NoiseHasher,
};

pub fn value_2d<NH>(point: [f64; 2], hasher: &NH) -> f64
where
    NH: NoiseHasher + ?Sized,
{
    let point = Vector2::from(point);

    let floored = point.floor();
    let corner = floored.numcast().unwrap();
    let weight = (point - floored).map_quintic();

    macro_rules! get(
        ($corner:expr, $offset:expr) => {
            {
               hasher.hash(&($corner + Vector2::from($offset)).into_array()) as f64 / 255.0
            }
        }
    );

    let f00 = get!(corner, [0, 0]);
    let f10 = get!(corner, [1, 0]);
    let f01 = get!(corner, [0, 1]);
    let f11 = get!(corner, [1, 1]);

    let d0 = interpolate::linear(f00, f10, weight.x);
    let d1 = interpolate::linear(f01, f11, weight.x);
    let d = interpolate::linear(d0, d1, weight.y);

    d * 2.0 - 1.0
}

pub fn value_3d<NH>(point: [f64; 3], hasher: &NH) -> f64
where
    NH: NoiseHasher + ?Sized,
{
    let point = Vector3::from(point);

    let floored = point.floor();
    let corner = floored.numcast().unwrap();
    let weight = (point - floored).map_quintic();

    macro_rules! get(
        ($corner:expr, $offset:expr) => {
            {
               hasher.hash(&($corner + Vector3::from($offset)).into_array()) as f64 / 255.0
            }
        }
    );

    let f000 = get!(corner, [0, 0, 0]);
    let f100 = get!(corner, [1, 0, 0]);
    let f010 = get!(corner, [0, 1, 0]);
    let f110 = get!(corner, [1, 1, 0]);
    let f001 = get!(corner, [0, 0, 1]);
    let f101 = get!(corner, [1, 0, 1]);
    let f011 = get!(corner, [0, 1, 1]);
    let f111 = get!(corner, [1, 1, 1]);

    let d00 = interpolate::linear(f000, f100, weight.x);
    let d01 = interpolate::linear(f001, f101, weight.x);
    let d10 = interpolate::linear(f010, f110, weight.x);
    let d11 = interpolate::linear(f011, f111, weight.x);
    let d0 = interpolate::linear(d00, d10, weight.y);
    let d1 = interpolate::linear(d01, d11, weight.y);
    let d = interpolate::linear(d0, d1, weight.z);

    d * 2.0 - 1.0
}

pub fn value_4d<NH>(point: [f64; 4], hasher: &NH) -> f64
where
    NH: NoiseHasher + ?Sized,
{
    let point = Vector4::from(point);

    let floored = point.floor();
    let corner = floored.numcast().unwrap();
    let weight = (point - floored).map_quintic();

    macro_rules! get(
        ($corner:expr, $offset:expr) => {
            {
               hasher.hash(&($corner + Vector4::from($offset)).into_array()) as f64 / 255.0
            }
        }
    );

    let f0000 = get!(corner, [0, 0, 0, 0]);
    let f1000 = get!(corner, [1, 0, 0, 0]);
    let f0100 = get!(corner, [0, 1, 0, 0]);
    let f1100 = get!(corner, [1, 1, 0, 0]);
    let f0010 = get!(corner, [0, 0, 1, 0]);
    let f1010 = get!(corner, [1, 0, 1, 0]);
    let f0110 = get!(corner, [0, 1, 1, 0]);
    let f1110 = get!(corner, [1, 1, 1, 0]);
    let f0001 = get!(corner, [0, 0, 0, 1]);
    let f1001 = get!(corner, [1, 0, 0, 1]);
    let f0101 = get!(corner, [0, 1, 0, 1]);
    let f1101 = get!(corner, [1, 1, 0, 1]);
    let f0011 = get!(corner, [0, 0, 1, 1]);
    let f1011 = get!(corner, [1, 0, 1, 1]);
    let f0111 = get!(corner, [0, 1, 1, 1]);
    let f1111 = get!(corner, [1, 1, 1, 1]);

    let d000 = interpolate::linear(f0000, f1000, weight.x);
    let d010 = interpolate::linear(f0010, f1010, weight.x);
    let d100 = interpolate::linear(f0100, f1100, weight.x);
    let d110 = interpolate::linear(f0110, f1110, weight.x);
    let d001 = interpolate::linear(f0001, f1001, weight.x);
    let d011 = interpolate::linear(f0011, f1011, weight.x);
    let d101 = interpolate::linear(f0101, f1101, weight.x);
    let d111 = interpolate::linear(f0111, f1111, weight.x);
    let d00 = interpolate::linear(d000, d100, weight.y);
    let d10 = interpolate::linear(d010, d110, weight.y);
    let d01 = interpolate::linear(d001, d101, weight.y);
    let d11 = interpolate::linear(d011, d111, weight.y);
    let d0 = interpolate::linear(d00, d10, weight.z);
    let d1 = interpolate::linear(d01, d11, weight.z);
    let d = interpolate::linear(d0, d1, weight.w);

    d * 2.0 - 1.0
}