s2json_core/geometry/
interpolate.rs

1use libm::round;
2
3use crate::{
4    BBOX, BBox, BBox3D, GetXY, GetZ, JSONProperties, JSONValue, MValue, Point, Point3D,
5    PointOrPoint3D, PrimitiveValue, STPoint, Value, ValuePrimitive, ValuePrimitiveType, ValueType,
6    VectorPoint,
7};
8
9/// Easy access to interpolation tooling for All S2JSON Core Types
10pub trait Interpolate {
11    /// Interpolate between two of the same type
12    fn interpolate(&self, other: &Self, t: f64) -> Self;
13}
14
15// Base types
16
17impl Interpolate for () {
18    fn interpolate(&self, _: &Self, _: f64) -> Self {}
19}
20macro_rules! impl_interpolate {
21    // truncate
22    ($($t:ty),* $(,)?) => {
23        $(
24            impl Interpolate for $t {
25                fn interpolate(&self, other: &Self, t: f64) -> Self {
26                    ((*self as f64) + ((*other as f64) - (*self as f64)) * t) as $t
27                }
28            }
29        )*
30    };
31
32    // round
33    (round: $($t:ty),* $(,)?) => {
34        $(
35            impl Interpolate for $t {
36                fn interpolate(&self, other: &Self, t: f64) -> Self {
37                    round((*self as f64) + ((*other as f64) - (*self as f64)) * t) as $t
38                }
39            }
40        )*
41    };
42}
43impl_interpolate!(f32);
44impl_interpolate!(round: usize, u8, u16, u32, u64, isize, i8, i16, i32, i64);
45impl Interpolate for f64 {
46    fn interpolate(&self, other: &Self, t: f64) -> Self {
47        self + (other - self) * t
48    }
49}
50impl<M: Interpolate> Interpolate for Option<M> {
51    fn interpolate(&self, other: &Self, t: f64) -> Self {
52        match (self, other) {
53            (Some(a), Some(b)) => Some(a.interpolate(b, t)),
54            _ => None,
55        }
56    }
57}
58
59// S2JSON Core Types
60
61impl Interpolate for Point {
62    fn interpolate(&self, other: &Self, t: f64) -> Self {
63        Point(self.x().interpolate(&other.x(), t), self.y().interpolate(&other.y(), t))
64    }
65}
66impl Interpolate for Point3D {
67    fn interpolate(&self, other: &Self, t: f64) -> Self {
68        Point3D(
69            self.0.interpolate(&other.0, t),
70            self.1.interpolate(&other.1, t),
71            self.2.interpolate(&other.2, t),
72        )
73    }
74}
75impl Interpolate for PointOrPoint3D {
76    fn interpolate(&self, other: &Self, t: f64) -> Self {
77        PointOrPoint3D(
78            self.x().interpolate(&other.x(), t),
79            self.y().interpolate(&other.y(), t),
80            self.z().interpolate(&other.z(), t),
81        )
82    }
83}
84impl<M: Interpolate> Interpolate for STPoint<M> {
85    fn interpolate(&self, other: &Self, t: f64) -> Self {
86        Self {
87            face: self.face,
88            s: self.s.interpolate(&other.s, t),
89            t: self.t.interpolate(&other.t, t),
90            z: self.z.interpolate(&other.z, t),
91            m: self.m.interpolate(&other.m, t),
92        }
93    }
94}
95impl<M: Interpolate + Clone> Interpolate for VectorPoint<M> {
96    fn interpolate(&self, other: &Self, t: f64) -> Self {
97        VectorPoint {
98            x: self.x.interpolate(&other.x, t),
99            y: self.y.interpolate(&other.y, t),
100            z: self.z.interpolate(&other.z, t),
101            m: self.m.interpolate(&other.m, t),
102            t: self.t.interpolate(&other.t, t),
103        }
104    }
105}
106
107// Value
108
109impl Interpolate for Value {
110    fn interpolate(&self, other: &Self, t: f64) -> Self {
111        let mut res = MValue::new();
112
113        // pairs are interpolated
114        for (a, b) in self.iter().zip(other.iter()) {
115            res.insert(a.0.clone(), a.1.interpolate(b.1, t));
116        }
117        // keys not in other are just added
118        for (k, v) in self.iter() {
119            if !res.contains_key(k) {
120                res.insert(k.clone(), v.clone());
121            }
122        }
123        // keys not in self are just added
124        for (k, v) in other.iter() {
125            if !res.contains_key(k) {
126                res.insert(k.clone(), v.clone());
127            }
128        }
129
130        res
131    }
132}
133impl Interpolate for ValueType {
134    fn interpolate(&self, other: &Self, t: f64) -> Self {
135        match (self, other) {
136            (ValueType::Primitive(a), ValueType::Primitive(b)) => {
137                ValueType::Primitive(a.interpolate(b, t))
138            }
139            (ValueType::Array(a), ValueType::Array(b)) => {
140                ValueType::Array(a.iter().zip(b.iter()).map(|(a, b)| a.interpolate(b, t)).collect())
141            }
142            (ValueType::Nested(a), ValueType::Nested(b)) => ValueType::Nested(a.interpolate(b, t)),
143            _ => ValueType::Primitive(PrimitiveValue::Null),
144        }
145    }
146}
147impl Interpolate for ValuePrimitiveType {
148    fn interpolate(&self, other: &Self, t: f64) -> Self {
149        match (self, other) {
150            (ValuePrimitiveType::Primitive(a), ValuePrimitiveType::Primitive(b)) => {
151                ValuePrimitiveType::Primitive(a.interpolate(b, t))
152            }
153            (ValuePrimitiveType::NestedPrimitive(a), ValuePrimitiveType::NestedPrimitive(b)) => {
154                ValuePrimitiveType::NestedPrimitive(a.interpolate(b, t))
155            }
156            _ => ValuePrimitiveType::Primitive(PrimitiveValue::Null),
157        }
158    }
159}
160impl Interpolate for ValuePrimitive {
161    fn interpolate(&self, other: &Self, t: f64) -> Self {
162        let mut res = ValuePrimitive::new();
163
164        // pairs are interpolated
165        for (a, b) in self.iter().zip(other.iter()) {
166            res.insert(a.0.clone(), a.1.interpolate(b.1, t));
167        }
168        // keys not in other are just added
169        for (k, v) in self.iter() {
170            if !res.contains_key(k) {
171                res.insert(k.clone(), v.clone());
172            }
173        }
174        // keys not in self are just added
175        for (k, v) in other.iter() {
176            if !res.contains_key(k) {
177                res.insert(k.clone(), v.clone());
178            }
179        }
180
181        res
182    }
183}
184impl Interpolate for PrimitiveValue {
185    fn interpolate(&self, other: &Self, t: f64) -> Self {
186        match (self, other) {
187            (PrimitiveValue::U64(a), PrimitiveValue::U64(b)) => {
188                PrimitiveValue::U64(a.interpolate(b, t))
189            }
190            (PrimitiveValue::I64(a), PrimitiveValue::I64(b)) => {
191                PrimitiveValue::I64(a.interpolate(b, t))
192            }
193            (PrimitiveValue::F32(a), PrimitiveValue::F32(b)) => {
194                PrimitiveValue::F32(a.interpolate(b, t))
195            }
196            (PrimitiveValue::F64(a), PrimitiveValue::F64(b)) => {
197                PrimitiveValue::F64(a.interpolate(b, t))
198            }
199            (PrimitiveValue::String(a), PrimitiveValue::String(b)) => {
200                PrimitiveValue::String(if t <= 0.5 { a.clone() } else { b.clone() })
201            }
202            (PrimitiveValue::Bool(a), PrimitiveValue::Bool(b)) => {
203                PrimitiveValue::Bool(if t <= 0.5 { *a } else { *b })
204            }
205            _ => self.clone(),
206        }
207    }
208}
209
210// JSONProperties
211
212impl Interpolate for JSONProperties {
213    fn interpolate(&self, other: &Self, t: f64) -> Self {
214        let mut res = JSONProperties::new();
215
216        // pairs are interpolated
217        for (a, b) in self.iter().zip(other.iter()) {
218            res.insert(a.0.clone(), a.1.interpolate(b.1, t));
219        }
220        // keys not in other are just added
221        for (k, v) in self.iter() {
222            if !res.contains_key(k) {
223                res.insert(k.clone(), v.clone());
224            }
225        }
226        // keys not in self are just added
227        for (k, v) in other.iter() {
228            if !res.contains_key(k) {
229                res.insert(k.clone(), v.clone());
230            }
231        }
232
233        res
234    }
235}
236impl Interpolate for JSONValue {
237    fn interpolate(&self, other: &Self, t: f64) -> Self {
238        match (self, other) {
239            (JSONValue::Primitive(a), JSONValue::Primitive(b)) => {
240                JSONValue::Primitive(a.interpolate(b, t))
241            }
242            (JSONValue::Array(a), JSONValue::Array(b)) => {
243                JSONValue::Array(a.iter().zip(b.iter()).map(|(a, b)| a.interpolate(b, t)).collect())
244            }
245            (JSONValue::Object(a), JSONValue::Object(b)) => JSONValue::Object(a.interpolate(b, t)),
246            _ => JSONValue::Primitive(PrimitiveValue::Null),
247        }
248    }
249}
250
251// BBox
252
253impl<T: Interpolate> Interpolate for BBox<T> {
254    fn interpolate(&self, other: &Self, t: f64) -> Self {
255        BBox {
256            left: self.left.interpolate(&other.left, t),
257            bottom: self.bottom.interpolate(&other.bottom, t),
258            right: self.right.interpolate(&other.right, t),
259            top: self.top.interpolate(&other.top, t),
260        }
261    }
262}
263impl<T: Interpolate> Interpolate for BBox3D<T> {
264    fn interpolate(&self, other: &Self, t: f64) -> Self {
265        BBox3D {
266            left: self.left.interpolate(&other.left, t),
267            bottom: self.bottom.interpolate(&other.bottom, t),
268            right: self.right.interpolate(&other.right, t),
269            top: self.top.interpolate(&other.top, t),
270            near: self.near.interpolate(&other.near, t),
271            far: self.far.interpolate(&other.far, t),
272        }
273    }
274}
275impl Interpolate for BBOX {
276    fn interpolate(&self, other: &Self, t: f64) -> Self {
277        match (self, other) {
278            (BBOX::BBox(a), BBOX::BBox(b)) => a.interpolate(b, t).into(),
279            (BBOX::BBox3D(a), BBOX::BBox3D(b)) => a.interpolate(b, t).into(),
280            // Ensure that BBox and BBox3D are ordered correctly
281            (BBOX::BBox(_), BBOX::BBox3D(_)) => *self,
282            (BBOX::BBox3D(_), BBOX::BBox(_)) => *self,
283        }
284    }
285}