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)?;
const NPOINT: usize = 12;
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,
},
];
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;
}
}
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;
}
}
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")?;
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;
}
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);
}