common/rust: add manhattan distance methods to Line

This commit is contained in:
Xiretza 2022-12-15 20:11:38 +01:00
parent 0b4b1d4f07
commit 3d47372967

View file

@ -28,6 +28,48 @@ impl Vec2 {
pub fn len(self) -> f64 {
(f64::from(self.x).powi(2) + f64::from(self.y).powi(2)).sqrt()
}
#[must_use]
pub fn manhattan_dist(self, other: Vec2) -> usize {
let Vec2 { x, y } = (other - self).map(i32::abs);
let x = usize::try_from(x).unwrap();
let y = usize::try_from(y).unwrap();
x + y
}
#[must_use]
pub fn on_x_with_manhattan_dist(self, x: i32, dist: usize) -> Option<(Vec2, Vec2)> {
let dx = usize::try_from((x - self.x).abs()).ok()?;
let dy = dist.checked_sub(dx)?;
let dy = i32::try_from(dy).ok()?;
let p1 = Vec2::new(x, self.y - dy);
let p2 = Vec2::new(x, self.y + dy);
debug_assert!(p1 <= p2);
debug_assert_eq!(self.manhattan_dist(p1), dist);
debug_assert_eq!(self.manhattan_dist(p2), dist);
Some((p1, p2))
}
#[must_use]
pub fn on_y_with_manhattan_dist(self, y: i32, dist: usize) -> Option<(Vec2, Vec2)> {
let dy = usize::try_from((y - self.y).abs()).ok()?;
let dx = dist.checked_sub(dy)?;
let dx = i32::try_from(dx).ok()?;
let p1 = Vec2::new(self.x - dx, y);
let p2 = Vec2::new(self.x + dx, y);
debug_assert!(p1 <= p2);
debug_assert_eq!(self.manhattan_dist(p1), dist);
debug_assert_eq!(self.manhattan_dist(p2), dist);
Some((p1, p2))
}
}
impl fmt::Display for Vec2 {