use crate::{core::Axis, geom::Vec2};
use super::{Float, Line2, Intersect};
#[derive(Clone, Copy, Default, Debug, PartialEq)]
pub struct Line1 {
a: Float,
b: Float,
}
impl Line1 {
pub fn new(a: Float, b: Float) -> Self {
Self { a, b }
}
pub fn validate(&mut self) {
if self.a > self.b {
std::mem::swap(&mut self.a, &mut self.b);
}
}
pub fn is_valid(&self) -> bool {
self.a < self.b
}
pub fn contains_point(&self, point: Float) -> bool {
point > self.a && point < self.b
}
pub fn contains(&self, other: &Self) -> bool {
self.contains_point(other.a) && self.contains_point(other.b)
}
pub fn into_line2(self, axis: Axis, n: Float) -> Line2 {
match axis {
Axis::Vertical => Line2::new(Vec2::new(n, self.a), Vec2::new(n, self.b)),
Axis::Horizontal => Line2::new(Vec2::new(self.a, n), Vec2::new(self.b, n)),
_ => panic!("Cannot convert using this kind of axis: {:?}", axis),
}
}
pub fn from_line2(other: Line2, axis: Axis) -> Self {
match axis {
Axis::Vertical => Self {a: other.a.y, b: other.b.y},
Axis::Horizontal => Self {a: other.a.x, b: other.b.x},
_ => panic!("Cannot convert using this kind of axis: {:?}", axis),
}
}
pub fn subtract(mut self, other: Self) -> Vec<Self> {
self.validate();
if !self.intersects(&other) {
return vec![self];
}
if self.contains(&other) {
return vec![Line1::new(self.a, other.a), Line1::new(other.b, self.b)];
}
if self.contains_point(other.a) {
return vec![Line1::new(self.a, other.a)];
}
if self.contains_point(other.b) {
return vec![Line1::new(other.b, self.b)];
}
return vec![self];
}
pub fn subtract_collection(old: Vec<Self>, other: Self) -> Vec<Self> {
let mut new = Vec::new();
for line in old {
new.extend(line.subtract(other.clone()));
}
return new;
}
}
impl Intersect<Self, Self> for Line1 {
fn intersection(&self, other: &Self) -> Option<Self> {
if !self.intersects(other) {
return None;
}
let min = if self.a > other.a { self.a } else { other.a };
let max = if self.b < other.b { self.b } else { other.b };
Some(Self::new(min, max))
}
fn intersects(&self, other: &Self) -> bool {
if self.a > other.b {
return false;
}
if other.a > self.b {
return false;
}
true
}
}