1use crate::{collections::segment_tree::index_types::GlobalIndex, math::FP64};
2use std::{fmt::Debug, ops::Deref};
3
4#[derive(Copy, Clone, PartialEq, Eq, Default)]
6pub struct Interval {
7 pub lo: FP64,
8 pub hi: FP64,
9}
10
11impl Debug for Interval {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 write!(f, "({},{})", self.lo, self.hi)
14 }
15}
16
17impl Interval {
18 pub fn from_point_and_length(t0: FP64, dt: FP64) -> Self {
20 Self {
21 lo: t0,
22 hi: t0 + dt,
23 }
24 }
25 pub fn from_length(dt: FP64) -> Self {
27 Self {
28 lo: FP64::zero(),
29 hi: dt,
30 }
31 }
32
33 pub fn clip_interval(mut self, bounds: Self) -> Self {
35 if self.hi > bounds.hi {
36 self.hi = bounds.hi;
37 }
38 if self.lo < bounds.lo {
39 self.lo = bounds.lo;
40 }
41 self
42 }
43
44 pub fn inverted(&self) -> bool {
45 self.lo > self.hi
46 }
47
48 pub fn is_seperating(&self, other_interval: &Self) -> bool {
49 let &Self { lo: lo_a, hi: hi_a } = self;
50
51 let &Self { lo: lo_b, hi: hi_b } = other_interval;
52
53 lo_b > hi_a || lo_a > hi_b
54 }
55
56 pub fn distance(&self) -> FP64 {
57 self.hi - self.lo
58 }
59
60 pub fn chunk(&self, num_chunks: u64, chunk_idx: usize) -> Self {
62 let num_chunks = FP64::from(num_chunks);
63 let chunk_idx = FP64::from(chunk_idx as u32);
64 let length = self.distance();
65 let chunk_length = length / num_chunks;
66 let lo = self.lo + chunk_length * chunk_idx;
67 Self {
68 lo,
69 hi: lo + chunk_length,
70 }
71 }
72
73 pub fn is_overlapping(&self, other_interval: &Self) -> bool {
74 !self.is_seperating(other_interval)
75 }
76
77 pub fn is_within(&self, t: FP64) -> bool {
78 let &Self { lo, hi } = self;
79 t >= lo && t <= hi
80 }
81
82 #[allow(dead_code)]
83 pub fn midpoint(&self) -> FP64 {
84 self.lo + (self.hi - self.lo) / FP64::from(2)
85 }
86
87 pub fn to_tuple(&self) -> (u128, u128) {
88 (self.lo.as_i64() as u128, self.hi.as_i64() as u128)
89 }
90 pub fn to_tuple_f32(&self) -> (f32, f32) {
91 (self.lo.as_f64() as f32, self.hi.as_f64() as f32)
92 }
93}
94
95impl<T> std::ops::Add<T> for Interval
96where
97 T: Into<u64> + Copy,
98{
99 type Output = Self;
100 fn add(self, rhs: T) -> Self::Output {
101 let rhs = FP64::from(T::into(rhs));
102 Self {
103 lo: self.lo + rhs,
104 hi: self.hi + rhs,
105 }
106 }
107}
108
109impl std::ops::Add<FP64> for Interval {
110 type Output = Self;
111 fn add(self, rhs: FP64) -> Self::Output {
112 Self {
113 lo: self.lo + rhs,
114 hi: self.hi + rhs,
115 }
116 }
117}
118
119impl From<(u64, u64)> for Interval {
120 fn from((lo, hi): (u64, u64)) -> Self {
121 Self {
122 lo: FP64::from(lo),
123 hi: FP64::from(hi),
124 }
125 }
126}
127impl From<(i64, i64)> for Interval {
128 fn from((lo, hi): (i64, i64)) -> Self {
129 Self {
130 lo: FP64::from(lo),
131 hi: FP64::from(hi),
132 }
133 }
134}
135impl From<(i32, i32)> for Interval {
136 fn from((lo, hi): (i32, i32)) -> Self {
137 Self {
138 lo: FP64::from(lo),
139 hi: FP64::from(hi),
140 }
141 }
142}
143impl From<(FP64, FP64)> for Interval {
144 fn from((lo, hi): (FP64, FP64)) -> Self {
145 Self { lo, hi }
146 }
147}
148
149#[derive(Copy, Clone, Debug)]
150pub struct GlobalInterval<V> {
151 pub interval: Interval,
152 pub data: V,
153}
154
155impl<V> Deref for GlobalInterval<V> {
156 type Target = Interval;
157 fn deref(&self) -> &Self::Target {
158 &self.interval
159 }
160}
161
162#[derive(Clone, Copy, Debug, Default)]
163pub struct TreeInterval {
164 pub clipped_interval: Interval,
165 pub global_idx: GlobalIndex,
166}
167
168impl Deref for TreeInterval {
169 type Target = Interval;
170 fn deref(&self) -> &Self::Target {
171 &self.clipped_interval
172 }
173}