common/rust: add Line type
This commit is contained in:
parent
26700274c3
commit
7db15c9cf7
1 changed files with 56 additions and 2 deletions
|
@ -6,8 +6,8 @@ use std::{
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Vec2 {
|
pub struct Vec2 {
|
||||||
x: i32, // increases toward right
|
pub x: i32, // increases toward right
|
||||||
y: i32, // increases toward top
|
pub y: i32, // increases toward top
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vec2 {
|
impl Vec2 {
|
||||||
|
@ -140,3 +140,57 @@ impl FromStr for Direction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A line from one point to another.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct Line {
|
||||||
|
pub start: Vec2,
|
||||||
|
pub end: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Line {
|
||||||
|
/// Returns an iterator over the line's points represented as [`Vec2`], including the start and
|
||||||
|
/// end points.
|
||||||
|
///
|
||||||
|
/// Only works for orthogonal lines.
|
||||||
|
#[must_use]
|
||||||
|
pub fn points(self) -> Option<LinePoints> {
|
||||||
|
LinePoints::try_from(self).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An iterator over a line's points. See [`Line::points()`] for details.
|
||||||
|
pub struct LinePoints {
|
||||||
|
line: Option<Line>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Line> for LinePoints {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(line: Line) -> Result<Self, Self::Error> {
|
||||||
|
if line.start.x == line.end.x || line.start.y == line.end.y {
|
||||||
|
Ok(Self { line: Some(line) })
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for LinePoints {
|
||||||
|
type Item = Vec2;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let Some(line) = self.line.as_mut() else { return None };
|
||||||
|
|
||||||
|
let delta = (line.end - line.start).map(i32::signum);
|
||||||
|
|
||||||
|
let p = line.start;
|
||||||
|
line.start += delta;
|
||||||
|
|
||||||
|
if delta == Vec2::new(0, 0) {
|
||||||
|
self.line = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue