1use crate::{core::Axis, geom::Vec2};
2
3use super::{Float, Line2, Intersect};
4
5#[derive(Clone, Copy, Default, Debug, PartialEq)]
7pub struct Line1 {
8 a: Float,
9 b: Float,
10}
11
12impl Line1 {
13 pub fn new(a: Float, b: Float) -> Self {
15 Self { a, b }
16 }
17
18 pub fn validate(&mut self) {
20 if self.a > self.b {
21 std::mem::swap(&mut self.a, &mut self.b);
22 }
23 }
24
25 pub fn is_valid(&self) -> bool {
27 self.a < self.b
28 }
29
30 pub fn contains_point(&self, point: Float) -> bool {
32 point > self.a && point < self.b
33 }
34
35 pub fn contains(&self, other: &Self) -> bool {
37 self.contains_point(other.a) && self.contains_point(other.b)
38 }
39
40 pub fn into_line2(self, axis: Axis, n: Float) -> Line2 {
42 match axis {
43 Axis::Vertical => Line2::new(Vec2::new(n, self.a), Vec2::new(n, self.b)),
44 Axis::Horizontal => Line2::new(Vec2::new(self.a, n), Vec2::new(self.b, n)),
45 _ => panic!("Cannot convert using this kind of axis: {:?}", axis),
46 }
47 }
48
49 pub fn from_line2(other: Line2, axis: Axis) -> Self {
51 match axis {
52 Axis::Vertical => Self {a: other.a.y, b: other.b.y},
53 Axis::Horizontal => Self {a: other.a.x, b: other.b.x},
54 _ => panic!("Cannot convert using this kind of axis: {:?}", axis),
55 }
56 }
57
58 pub fn subtract(mut self, other: Self) -> Vec<Self> {
60 self.validate();
61 if !self.intersects(&other) {
62 return vec![self];
63 }
64 if self.contains(&other) {
65 return vec![Line1::new(self.a, other.a), Line1::new(other.b, self.b)];
66 }
67 if self.contains_point(other.a) {
68 return vec![Line1::new(self.a, other.a)];
69 }
70 if self.contains_point(other.b) {
71 return vec![Line1::new(other.b, self.b)];
72 }
73 return vec![self];
74 }
75
76 pub fn subtract_collection(old: Vec<Self>, other: Self) -> Vec<Self> {
78 let mut new = Vec::new();
79 for line in old {
80 new.extend(line.subtract(other.clone()));
81 }
82 return new;
83 }
84}
85
86impl Intersect<Self, Self> for Line1 {
87 fn intersection(&self, other: &Self) -> Option<Self> {
88 if !self.intersects(other) {
89 return None;
90 }
91
92 let min = if self.a > other.a { self.a } else { other.a };
93 let max = if self.b < other.b { self.b } else { other.b };
94 Some(Self::new(min, max))
95 }
96
97 fn intersects(&self, other: &Self) -> bool {
98 if self.a > other.b {
99 return false;
100 }
101 if other.a > self.b {
102 return false;
103 }
104 true
105 }
106}