gemlab 2.0.0

Geometry and meshes laboratory for finite element analyses
Documentation
use gemlab::geometry::{Circle2d, Point2d};
use gemlab::util::GridSearch;
use gemlab::StrError;
use plotpy::Plot;
use russell_lab::math::PI;
use std::collections::HashSet;

struct Segment {
    a: [f64; 2],
    b: [f64; 2],
}

fn main() -> Result<(), StrError> {
    let xmin = &[0.0, 0.0];
    let xmax = &[10.0, 10.0];
    let mut grid = GridSearch::new(xmin, xmax, None, None, None)?;

    // number of points in each entity
    const NPOINT: usize = 12;

    // circles
    let circles = vec![
        Circle2d {
            center: Point2d::new(5.0, 2.0),
            radius: 1.0,
        },
        Circle2d {
            center: Point2d::new(7.5, 5.0),
            radius: 1.2,
        },
        Circle2d {
            center: Point2d::new(5.0, 7.5),
            radius: 1.4,
        },
        Circle2d {
            center: Point2d::new(2.5, 5.0),
            radius: 1.2,
        },
    ];

    // add points to grid
    let mut id = 0;
    let mut x = vec![0.0; 2];
    for c in &circles {
        for n in 0..NPOINT {
            let alpha = (n as f64) * 2.0 * PI / (NPOINT as f64);
            x[0] = c.center.x + c.radius * f64::cos(alpha);
            x[1] = c.center.y + c.radius * f64::sin(alpha);
            grid.insert(id, &x)?;
            id += 1;
        }
    }

    // segments
    let segments = vec![
        Segment {
            a: [0.0, 0.0],
            b: [10.0, 10.0],
        },
        Segment {
            a: [0.0, 10.0],
            b: [10.0, 0.0],
        },
    ];
    for s in &segments {
        for n in 0..NPOINT {
            x[0] = s.a[0] + (n as f64) * (s.b[0] - s.a[0]) / ((NPOINT - 1) as f64);
            x[1] = s.a[1] + (n as f64) * (s.b[1] - s.a[1]) / ((NPOINT - 1) as f64);
            grid.insert(id, &x)?;
            id += 1;
        }
    }

    // draw grid
    let mut plot = Plot::new();
    grid.draw(&mut plot, false)?;
    plot.set_equal_axes(true)
        .set_figure_size_points(600.0, 600.0)
        .save("/tmp/gemlab/example_search_in_grid_2d.svg")?;

    // search points on circles
    let mut start_id = 0;
    let mut end_id = NPOINT;
    for c in &circles {
        let res = grid.search_on_circle(&[c.center.x, c.center.y], c.radius, |_| true)?;
        check(&res, &(start_id..end_id).collect::<Vec<_>>());
        start_id += NPOINT;
        end_id += NPOINT;
    }

    // search points on segments
    for s in &segments {
        let res = grid.search_on_line(&s.a, &s.b, |_| true)?;
        check(&res, &(start_id..end_id).collect::<Vec<_>>());
        start_id += NPOINT;
        end_id += NPOINT;
    }

    Ok(())
}

fn check<T>(found: &HashSet<T>, correct: &[T])
where
    T: Copy + Ord + std::fmt::Debug,
{
    let mut ids: Vec<T> = found.iter().copied().collect();
    ids.sort();
    assert_eq!(ids, correct);
}