mod edge; #[cfg(test)] mod tests { use std::collections::HashSet; use i_float::point::IntPoint; use rand::Rng; use crate::edge::cross_solver::CrossSolver; use crate::edge::direct_solver::DirectPointSolver; use crate::edge::segment::{IdSegment, Segment}; use crate::edge::tree_solver::TreePointSolver; #[test] fn test_00() { let edges = vec![ IdSegment { index: 1, segment: Segment::new(IntPoint { x: 3, y: 3 }, IntPoint { x: 4, y: 2 }) }, IdSegment { index: 0, segment: Segment::new(IntPoint { x: 4, y: 1 }, IntPoint { x: 6, y: 7 }) }, IdSegment { index: 2, segment: Segment::new(IntPoint { x: 5, y: 1 }, IntPoint { x: 6, y: 0 }) }, ]; let points = vec![IntPoint { x: 3, y: 7 }, IntPoint { x: 5, y: 7 }]; let result0 = DirectPointSolver::run(&edges, &points); let result1 = TreePointSolver::run(&edges, &points); assert_eq!(result0, result1); } #[test] fn test_01() { let edges = vec![ IdSegment { index: 0, segment: Segment::new(IntPoint { x: 1, y: 5 }, IntPoint { x: 1, y: 6 }) }, IdSegment { index: 1, segment: Segment::new(IntPoint { x: 1, y: 5 }, IntPoint { x: 6, y: 0 }) }, IdSegment { index: 2, segment: Segment::new(IntPoint { x: 1, y: 3 }, IntPoint { x: 2, y: 2 }) }, IdSegment { index: 3, segment: Segment::new(IntPoint { x: 4, y: 4 }, IntPoint { x: 5, y: 5 }) }, ]; let points = vec![IntPoint { x: 1, y: 7 }]; let result0 = DirectPointSolver::run(&edges, &points); let result1 = TreePointSolver::run(&edges, &points); assert_eq!(result0, result1); } #[test] fn test_02() { let edges = vec![ IdSegment { index: 3, segment: Segment::new(IntPoint { x: 0, y: 3 }, IntPoint { x: 7, y: 6 }) }, IdSegment { index: 5, segment: Segment::new(IntPoint { x: 0, y: 5 }, IntPoint { x: 0, y: 5 }) }, IdSegment { index: 2, segment: Segment::new(IntPoint { x: 1, y: 0 }, IntPoint { x: 7, y: 5 }) }, IdSegment { index: 4, segment: Segment::new(IntPoint { x: 1, y: 4 }, IntPoint { x: 2, y: 4 }) }, IdSegment { index: 7, segment: Segment::new(IntPoint { x: 1, y: 4 }, IntPoint { x: 2, y: 5 }) }, IdSegment { index: 6, segment: Segment::new(IntPoint { x: 2, y: 2 }, IntPoint { x: 2, y: 2 }) }, IdSegment { index: 0, segment: Segment::new(IntPoint { x: 3, y: 3 }, IntPoint { x: 4, y: 4 }) }, IdSegment { index: 1, segment: Segment::new(IntPoint { x: 3, y: 3 }, IntPoint { x: 4, y: 3 }) }, ]; let points = vec![ IntPoint { x: 2, y: 1 }, IntPoint { x: 3, y: 1 }, IntPoint { x: 6, y: 5 }, IntPoint { x: 6, y: 4 }, IntPoint { x: 6, y: 0 }, ]; let result0 = DirectPointSolver::run(&edges, &points); let result1 = TreePointSolver::run(&edges, &points); assert_eq!(result0, result1); } #[test] fn test_single_random() { let edges = random_edges(0..10, 2..6, 20); let points = random_points(0..10, 20, &edges); let result0 = DirectPointSolver::run(&edges, &points); let result1 = TreePointSolver::run(&edges, &points); assert_eq!(result0, result1, "Edges: {:?}\nPoints: {:?}", edges, points); } #[test] fn test_small_random() { for _ in 0..10000 { let edges = random_edges(0..8, 2..6, 8); let points = random_points(0..8, 5, &edges); let result0 = DirectPointSolver::run(&edges, &points); let result1 = TreePointSolver::run(&edges, &points); let is_equal = result0 == result1; if !is_equal { assert_eq!(result0, result1, "Edges: {:?}\nPoints: {:?}", edges, points); } } } fn random_edges(range: std::ops::Range, length: std::ops::Range, count: usize) -> Vec { let list = CrossSolver::random_segments(range, length, count); let mut result = Vec::with_capacity(list.len()); for i in 0..list.len() { let e = &list[i]; let segment = if e.a.x <= e.b.x { Segment::new(e.a, e.b) } else { Segment::new(e.b, e.a) }; result.push(IdSegment { index: i, segment }); } result.sort_by(|s0, s1| s0.segment.a.x.cmp(&s1.segment.a.x)); result } fn random_points(range: std::ops::Range, count: usize, exclude: &Vec) -> Vec { let mut p_set: HashSet = HashSet::with_capacity(2 * exclude.len()); for e in exclude.iter() { p_set.insert(e.segment.a.clone()); p_set.insert(e.segment.b.clone()); } let mut rng = rand::thread_rng(); let mut result = Vec::with_capacity(count); while result.len() < count { let p = IntPoint { x: rng.gen_range(range.clone()), y: rng.gen_range(range.clone()), }; if !p_set.contains(&p) { p_set.insert(p); result.push(p); } } result.sort_by(|a, b| a.x.cmp(&b.x)); result } }