Basic boundary detection

This commit is contained in:
numzero 2024-05-05 16:27:30 +03:00
parent 363ee4914b
commit bcae0a4435

View File

@ -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<Vec2>);
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 { mod riemann {
use glam::*; use glam::*;