cg-math 0.1.2

A computer graphics library focused on usage with cg-lab.
Documentation
use std::time::Instant;

use rand::{distributions::Uniform, rngs::ThreadRng, thread_rng, Rng};
use cg_math::{
    self,
    algos::{bw, ric},
    geometry::{WeightedTriangle, WeightedVertex, Triangulation},
    validation::{all_globally_regular, is_c_hull, summed_area},
};

fn setup() -> Vec<(
    &'static str,
    fn(&mut Vec<WeightedVertex>, f64) -> Triangulation,
)> {
    vec![
        ("Bowyer_Watson", bw::compute2d),
        ("Randomized_Incremental", ric::compute2d),
    ]
}

fn run_test(mut vertices: Vec<WeightedVertex>, epsilon: f64) {
    let algorithms = setup();

    for (algo_name, algo) in algorithms {
        let start = Instant::now();
        let triangulation = algo(&mut vertices, epsilon);
        let end = Instant::now();
        let duration = end.duration_since(start).as_secs_f64();

        let mut results = validate_triangulation(&vertices, triangulation.triangles(), algo_name, duration);
        results.push(duration);
    }
}

fn validate_triangulation(
    vertices: &Vec<WeightedVertex>,
    triangles: &Vec<WeightedTriangle>,
    algo_name: &str,
    algo_duration: f64,
) -> Vec<f64> {
    println!("---------------------------------------------------------");
    println!("Validating the {} triangulation...", algo_name);
    let regularity_percentage = all_globally_regular(vertices, triangles);
    let is_c_hull = is_c_hull(vertices, triangles);
    let area = summed_area(triangles);
    println!("#Triangles: {}", triangles.len());
    println!("Regularity: {}", regularity_percentage);
    println!(" Is c-hull: {}", is_c_hull);
    println!("Total area: {}", area);
    println!(" Time in s: {:.4}", algo_duration);
    println!("---------------------------------------------------------\n");

    vec![
        0.0,
        triangles.len() as f64,
        is_c_hull as i32 as f64,
        regularity_percentage,
        area,
    ]
}

#[test]
fn minimal_delaunay_triangulation4() {
    let vertices = vec![
        WeightedVertex::new(1.2, 0.8, 0.0),
        WeightedVertex::new(3.0, 1.9, 0.0),
        WeightedVertex::new(1.6, 3.3, 0.0),
        WeightedVertex::new(2.0, 2.0, 0.1),
    ];
    run_test(vertices, 15.6);
}

#[test]
fn minimal_regular_triangulation4() {
    let vertices = vec![
        WeightedVertex::new(1.2, 0.8, 10.0),
        WeightedVertex::new(3.0, 1.9, 1.0),
        WeightedVertex::new(1.6, 3.3, 1.0),
        WeightedVertex::new(2.0, 2.0, 0.1),
    ];
    run_test(vertices, 0.0);
}

#[test]
fn minimal_delaunay_triangulation8() {
    let vertices = vec![
        WeightedVertex::new(4.0, 5.0, 0.0),
        WeightedVertex::new(3.0, 2.0, 0.0),
        WeightedVertex::new(1.0, 0.0, 0.0),
        WeightedVertex::new(8.0, 9.0, 0.0),
        WeightedVertex::new(7.0, 4.0, 0.0),
        WeightedVertex::new(5.0, 2.0, 0.0),
        WeightedVertex::new(6.0, 3.0, 0.0),
        WeightedVertex::new(10.0, 1.0, 0.0),
    ];
    run_test(vertices, 0.0);
}

#[test]
fn minimal_regular_triangulation8() {
    let vertices = vec![
        WeightedVertex::new(4.0, 5.0, 20.0),
        WeightedVertex::new(3.0, 2.0, 6.0),
        WeightedVertex::new(1.0, 0.0, 0.1),
        WeightedVertex::new(8.0, 9.0, 17.0),
        WeightedVertex::new(7.0, 4.0, 441.0 / 19.0),
        WeightedVertex::new(5.0, 2.0, 10.0),
        WeightedVertex::new(6.0, 3.0, 18.0),
        WeightedVertex::new(10.0, 1.0, 30.0),
    ];
    run_test(vertices, 0.0);
}

#[test]
fn random_delaunay_triangulation50() {
    const N_VERTICES: i32 = 1000;
    let mut rng: ThreadRng = thread_rng();
    let distribution: Uniform<f64> = Uniform::new(0.0, 10.0);

    // generate random vertices, uniformly distributed
    let vals_x: Vec<f64> = (0..N_VERTICES).map(|_| rng.sample(&distribution)).collect();
    let vals_y: Vec<f64> = (0..N_VERTICES).map(|_| rng.sample(&distribution)).collect();
    let mut vertices: Vec<WeightedVertex> = vec![];
    for i in 0..vals_x.len() {
        vertices.push(WeightedVertex::new(vals_x[i], vals_y[i], 0.0));
    }

    run_test(vertices, 0.0);
}

#[test]
fn random_regular_triangulation50() {
    const N_VERTICES: i32 = 50;
    let mut rng: ThreadRng = thread_rng();
    let distribution: Uniform<f64> = Uniform::new(0.0, 1.0);

    // generate random vertices, uniformly distributed
    let vals_x: Vec<f64> = (0..N_VERTICES).map(|_| rng.sample(&distribution)).collect();
    let vals_y: Vec<f64> = (0..N_VERTICES).map(|_| rng.sample(&distribution)).collect();
    let vals_w: Vec<f64> = (0..N_VERTICES).map(|_| rng.sample(&distribution)).collect();
    let mut vertices: Vec<WeightedVertex> = vec![];
    for i in 0..vals_x.len() {
        vertices.push(WeightedVertex::new(vals_x[i], vals_y[i], vals_w[i]));
    }

    run_test(vertices, 0.0);
}