diff --git a/src/bin/flat.rs b/src/bin/flat.rs index 4c8fb38..58bfc74 100644 --- a/src/bin/flat.rs +++ b/src/bin/flat.rs @@ -124,6 +124,46 @@ impl Metric for Rect { } } +mod boundary { + use glam::*; + + struct Id(u8); + + trait Boundary { + fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(Id, Vec2, Vec2)>; + } + + struct Loop(Vec); + + impl Loop { + fn hit(&self, base: Vec2, dir: Vec2) -> Option<(usize, f32)> { + self.0.iter().enumerate().filter_map(|(k, &a)| { + let b = self.0[(k + 1) % self.0.len()]; + let u = mat2(a - base, dir).determinant(); + let v = mat2(b - base, dir).determinant(); + if u < 0.0 && v > 0.0 { + let dist = mat2(a - base, b - a).determinant() / mat2(dir, b - a).determinant(); + if dist >= 0.0 { Some((k, dist)) } else { None } + } else { + None + } + }).min_by(|(k1, dist1), (k2, dist2)| dist1.total_cmp(dist2)) + } + } + + #[test] + fn test_loop() { + let tri = Loop(vec![vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(0.0, 1.0)]); + assert_eq!(tri.hit(vec2(0.0, -2.0), vec2(0.0, 1.0)), Some((0, 1.0))); + assert_eq!(tri.hit(vec2(0.0, -2.0), vec2(0.0, 0.5)), Some((0, 2.0))); + assert_eq!(tri.hit(vec2(0.0, -2.0), vec2(1.0, 1.0)), None); + assert_eq!(tri.hit(vec2(0.0, 0.0), vec2(0.0, 1.0)), None); + assert_eq!(tri.hit(vec2(0.0, 0.0), vec2(0.0, -1.0)), None); + assert_eq!(tri.hit(vec2(-1.5, 0.5), vec2(2.0, -1.0)), Some((2, 0.5))); + assert_eq!(tri.hit(vec2(-1.5, 0.5), vec2(-2.0, 1.0)), None); + } +} + mod riemann { use glam::*;