plottery_lib 0.14.1

Core geometry library of Plottery, a creative coding framework for generative vector graphics and pen plotting.
Documentation
#[cfg(test)]
mod test_noise {
    use rand::random;

    use crate::{
        maths::thread_local::{seed, seed_random},
        perlin_2d, perlin_3d, simplex_2d, simplex_3d, worley_2d, worley_3d, MarchingSquares, Noise,
        NoiseScale, NoiseSettings, Rect, SampleSettings, V2,
    };

    #[test]
    fn test_noise_value_range() {
        println!("perlin_2d");
        test_noise_range_helper(perlin_2d);
        println!("simplex_2d");
        test_noise_range_helper(simplex_2d);
        println!("worley_2d");
        test_noise_range_helper(worley_2d);
    }
    fn test_noise_range_helper(noise: fn(V2) -> f32) {
        for _ in 0..10000 {
            let location = V2::new(
                random::<f32>() * 1000.0 - 500.0,
                random::<f32>() * 1000.0 - 500.0,
            );
            let noise = noise(location);
            assert!((0.0..=1.0).contains(&noise));
        }
    }

    #[test]
    fn as_fn_matches_get() {
        let noise = Noise::perlin().seed(3);
        let field = noise.as_fn();
        let p = V2::new(0.3, 0.7);
        assert_eq!(field(p), noise.get(p));
        let squares = MarchingSquares::new(
            Rect::new(V2::zero(), V2::xy(1.0)),
            SampleSettings::new(4.0),
            noise.as_fn(),
        );
        let _ = squares.lines(0.5);
    }

    #[test]
    fn test_noise_seed() {
        println!("perlin_2d");
        test_noise_seed_helper(perlin_2d);
        println!("simplex_2d");
        test_noise_seed_helper(simplex_2d);
        println!("worley_2d");
        test_noise_seed_helper(worley_2d);
    }
    fn test_noise_seed_helper(noise: fn(V2) -> f32) {
        seed(1);
        let noise1 = noise(V2::new(0.5, 0.5));
        let noise2 = noise(V2::new(0.5, 0.5));
        assert_eq!(noise1, noise2); // same location should result in same value

        seed(2);
        let noise3 = noise(V2::new(0.5, 0.5));
        let noise4 = noise(V2::new(0.5, 0.5));
        assert_eq!(noise3, noise4); // same location should result in same value
        assert_ne!(noise1, noise3); // different seed should result in different value
        assert_ne!(noise1, noise4);

        // using seed_random should result in different values each time
        seed_random();
        let noise5 = noise(V2::new(0.5, 0.5));
        std::thread::sleep(std::time::Duration::from_millis(5)); // necessary because SystemTime::now is used as seed
        seed_random();
        let noise6 = noise(V2::new(0.5, 0.5));
        assert_ne!(noise5, noise6)
    }

    #[test]
    fn test_noise_location() {
        println!("perlin");
        test_noise_location_helper(perlin_2d, perlin_3d);
        println!("simplex");
        test_noise_location_helper(simplex_2d, simplex_3d);
        println!("worley");
        test_noise_location_helper(worley_2d, worley_3d);
    }
    fn test_noise_location_helper(noise_2d: fn(V2) -> f32, noise_3d: fn(f32, f32, f32) -> f32) {
        seed(12312);
        let noise1 = noise_2d(V2::new(0.5, 0.5));
        let noise2 = noise_2d(V2::new(0.47, 0.53));
        assert_ne!(noise1, noise2);

        seed(41232);
        let noise1 = noise_3d(0.5, 0.5, 0.5);
        let noise2 = noise_3d(0.47, 0.53, 0.5);
        assert_ne!(noise1, noise2);
    }

    #[test]
    fn test_noise_settings_per_paper_divides_frequency() {
        let size = V2::new(20.0, 40.0);
        let settings = NoiseSettings::default()
            .with_frequency(4.0)
            .with_scale(NoiseScale::PerPaper);

        // explicit seeds: the global RNG is shared with tests running in parallel
        let per_paper = settings.noise_for(size).seed(7);
        let absolute = settings.with_frequency(4.0 / 20.0).noise().seed(7);
        for i in 0..20 {
            let p = V2::new(i as f32 * 1.3, i as f32 * 0.7);
            assert_eq!(per_paper.get(p), absolute.get(p));
        }

        let per_cm = settings
            .with_scale(NoiseScale::PerCm)
            .noise_for(size)
            .seed(7);
        assert_eq!(
            per_cm.get(V2::xy(2.0)),
            settings.noise().seed(7).get(V2::xy(2.0))
        );
    }
}