s2json_core/geometry/
interpolate.rs

1use libm::round;
2
3use crate::{
4    GetXY, GetZ, MValue, Point, Point3D, PointOrPoint3D, PrimitiveValue, STPoint, Value,
5    ValuePrimitive, ValuePrimitiveType, ValueType, VectorPoint,
6};
7
8/// Easy access to interpolation tooling for All S2JSON Core Types
9pub trait Interpolate {
10    /// Interpolate between two of the same type
11    fn interpolate(&self, other: &Self, t: f64) -> Self;
12}
13impl Interpolate for u64 {
14    fn interpolate(&self, other: &Self, t: f64) -> Self {
15        round((*self as f64) + ((*other as f64) - (*self as f64)) * t) as u64
16    }
17}
18impl Interpolate for i64 {
19    fn interpolate(&self, other: &Self, t: f64) -> Self {
20        round((*self as f64) + ((*other as f64) - (*self as f64)) * t) as i64
21    }
22}
23impl Interpolate for f32 {
24    fn interpolate(&self, other: &Self, t: f64) -> Self {
25        ((*self as f64) + ((*other as f64) - (*self as f64)) * t) as f32
26    }
27}
28impl Interpolate for f64 {
29    fn interpolate(&self, other: &Self, t: f64) -> Self {
30        self + (other - self) * t
31    }
32}
33impl<M: Interpolate> Interpolate for Option<M> {
34    fn interpolate(&self, other: &Self, t: f64) -> Self {
35        match (self, other) {
36            (Some(a), Some(b)) => Some(a.interpolate(b, t)),
37            _ => None,
38        }
39    }
40}
41impl Interpolate for Point {
42    fn interpolate(&self, other: &Self, t: f64) -> Self {
43        Point(self.x().interpolate(&other.x(), t), self.y().interpolate(&other.y(), t))
44    }
45}
46impl Interpolate for Point3D {
47    fn interpolate(&self, other: &Self, t: f64) -> Self {
48        Point3D(
49            self.0.interpolate(&other.0, t),
50            self.1.interpolate(&other.1, t),
51            self.2.interpolate(&other.2, t),
52        )
53    }
54}
55impl Interpolate for PointOrPoint3D {
56    fn interpolate(&self, other: &Self, t: f64) -> Self {
57        PointOrPoint3D(
58            self.x().interpolate(&other.x(), t),
59            self.y().interpolate(&other.y(), t),
60            self.z().interpolate(&other.z(), t),
61        )
62    }
63}
64impl<M: Interpolate> Interpolate for STPoint<M> {
65    fn interpolate(&self, other: &Self, t: f64) -> Self {
66        Self {
67            face: self.face,
68            s: self.s.interpolate(&other.s, t),
69            t: self.t.interpolate(&other.t, t),
70            z: self.z.interpolate(&other.z, t),
71            m: self.m.interpolate(&other.m, t),
72        }
73    }
74}
75impl<M: Interpolate + Clone> Interpolate for VectorPoint<M> {
76    fn interpolate(&self, other: &Self, t: f64) -> Self {
77        VectorPoint {
78            x: self.x.interpolate(&other.x, t),
79            y: self.y.interpolate(&other.y, t),
80            z: self.z.interpolate(&other.z, t),
81            m: self.m.interpolate(&other.m, t),
82            t: self.t.interpolate(&other.t, t),
83        }
84    }
85}
86impl Interpolate for Value {
87    fn interpolate(&self, other: &Self, t: f64) -> Self {
88        let mut res = MValue::new();
89
90        // pairs are interpolated
91        for (a, b) in self.iter().zip(other.iter()) {
92            res.insert(a.0.clone(), a.1.interpolate(b.1, t));
93        }
94        // keys not in other are just added
95        for (k, v) in self.iter() {
96            if !res.contains_key(k) {
97                res.insert(k.clone(), v.clone());
98            }
99        }
100        // keys not in self are just added
101        for (k, v) in other.iter() {
102            if !res.contains_key(k) {
103                res.insert(k.clone(), v.clone());
104            }
105        }
106
107        res
108    }
109}
110impl Interpolate for ValueType {
111    fn interpolate(&self, other: &Self, t: f64) -> Self {
112        match (self, other) {
113            (ValueType::Primitive(a), ValueType::Primitive(b)) => {
114                ValueType::Primitive(a.interpolate(b, t))
115            }
116            (ValueType::Array(a), ValueType::Array(b)) => {
117                ValueType::Array(a.iter().zip(b.iter()).map(|(a, b)| a.interpolate(b, t)).collect())
118            }
119            (ValueType::Nested(a), ValueType::Nested(b)) => ValueType::Nested(a.interpolate(b, t)),
120            _ => ValueType::Primitive(PrimitiveValue::Null),
121        }
122    }
123}
124impl Interpolate for ValuePrimitiveType {
125    fn interpolate(&self, other: &Self, t: f64) -> Self {
126        match (self, other) {
127            (ValuePrimitiveType::Primitive(a), ValuePrimitiveType::Primitive(b)) => {
128                ValuePrimitiveType::Primitive(a.interpolate(b, t))
129            }
130            (ValuePrimitiveType::NestedPrimitive(a), ValuePrimitiveType::NestedPrimitive(b)) => {
131                ValuePrimitiveType::NestedPrimitive(a.interpolate(b, t))
132            }
133            _ => ValuePrimitiveType::Primitive(PrimitiveValue::Null),
134        }
135    }
136}
137impl Interpolate for ValuePrimitive {
138    fn interpolate(&self, other: &Self, t: f64) -> Self {
139        let mut res = ValuePrimitive::new();
140
141        // pairs are interpolated
142        for (a, b) in self.iter().zip(other.iter()) {
143            res.insert(a.0.clone(), a.1.interpolate(b.1, t));
144        }
145        // keys not in other are just added
146        for (k, v) in self.iter() {
147            if !res.contains_key(k) {
148                res.insert(k.clone(), v.clone());
149            }
150        }
151        // keys not in self are just added
152        for (k, v) in other.iter() {
153            if !res.contains_key(k) {
154                res.insert(k.clone(), v.clone());
155            }
156        }
157
158        res
159    }
160}
161impl Interpolate for PrimitiveValue {
162    fn interpolate(&self, other: &Self, t: f64) -> Self {
163        match (self, other) {
164            (PrimitiveValue::U64(a), PrimitiveValue::U64(b)) => {
165                PrimitiveValue::U64(a.interpolate(b, t))
166            }
167            (PrimitiveValue::I64(a), PrimitiveValue::I64(b)) => {
168                PrimitiveValue::I64(a.interpolate(b, t))
169            }
170            (PrimitiveValue::F32(a), PrimitiveValue::F32(b)) => {
171                PrimitiveValue::F32(a.interpolate(b, t))
172            }
173            (PrimitiveValue::F64(a), PrimitiveValue::F64(b)) => {
174                PrimitiveValue::F64(a.interpolate(b, t))
175            }
176            (PrimitiveValue::String(a), PrimitiveValue::String(b)) => {
177                PrimitiveValue::String(if t <= 0.5 { a.clone() } else { b.clone() })
178            }
179            (PrimitiveValue::Bool(a), PrimitiveValue::Bool(b)) => {
180                PrimitiveValue::Bool(if t <= 0.5 { *a } else { *b })
181            }
182            _ => self.clone(),
183        }
184    }
185}