rstar/
point.rs

1use core::fmt::Debug;
2use num_traits::{Bounded, Num, Signed, Zero};
3
4/// Defines a number type that is compatible with rstar.
5///
6/// rstar works out of the box with the following standard library types:
7///  - i32
8///  - i64
9///  - f32
10///  - f64
11///
12/// This type cannot be implemented directly. Instead, it is required to implement
13/// all required traits from the `num_traits` crate.
14///
15/// # Example
16/// ```
17/// # extern crate num_traits;
18/// use num_traits::{Bounded, Num, Signed};
19///
20/// #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
21/// struct MyFancyNumberType(f32);
22///
23/// impl Bounded for MyFancyNumberType {
24///   // ... details hidden ...
25/// # fn min_value() -> Self { MyFancyNumberType(Bounded::min_value()) }
26/// #
27/// # fn max_value() -> Self { MyFancyNumberType(Bounded::max_value()) }
28/// }
29///
30/// impl Signed for MyFancyNumberType {
31///   // ... details hidden ...
32/// # fn abs(&self) -> Self { unimplemented!() }
33/// #
34/// # fn abs_sub(&self, other: &Self) -> Self { unimplemented!() }
35/// #
36/// # fn signum(&self) -> Self { unimplemented!() }
37/// #
38/// # fn is_positive(&self) -> bool { unimplemented!() }
39/// #
40/// # fn is_negative(&self) -> bool { unimplemented!() }
41/// }
42///
43/// impl Num for MyFancyNumberType {
44///   // ... details hidden ...
45/// # type FromStrRadixErr = num_traits::ParseFloatError;
46/// # fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { unimplemented!() }
47/// }
48///
49/// // Lots of traits are still missing to make the above code compile, but
50/// // let's assume they're implemented. `MyFancyNumberType` type now readily implements
51/// // RTreeNum and can be used with r-trees:
52/// # fn main() {
53/// use rstar::RTree;
54/// let mut rtree = RTree::new();
55/// rtree.insert([MyFancyNumberType(0.0), MyFancyNumberType(0.0)]);
56/// # }
57///
58/// # impl num_traits::Zero for MyFancyNumberType {
59/// #   fn zero() -> Self { unimplemented!() }
60/// #   fn is_zero(&self) -> bool { unimplemented!() }
61/// # }
62/// #
63/// # impl num_traits::One for MyFancyNumberType {
64/// #   fn one() -> Self { unimplemented!() }
65/// # }
66/// #
67/// # impl core::ops::Mul for MyFancyNumberType {
68/// #   type Output = Self;
69/// #   fn mul(self, rhs: Self) -> Self { unimplemented!() }
70/// # }
71/// #
72/// # impl core::ops::Add for MyFancyNumberType {
73/// #   type Output = Self;
74/// #   fn add(self, rhs: Self) -> Self { unimplemented!() }
75/// # }
76/// #
77/// # impl core::ops::Sub for MyFancyNumberType {
78/// #   type Output = Self;
79/// #   fn sub(self, rhs: Self) -> Self { unimplemented!() }
80/// # }
81/// #
82/// # impl core::ops::Div for MyFancyNumberType {
83/// #   type Output = Self;
84/// #   fn div(self, rhs: Self) -> Self { unimplemented!() }
85/// # }
86/// #
87/// # impl core::ops::Rem for MyFancyNumberType {
88/// #   type Output = Self;
89/// #   fn rem(self, rhs: Self) -> Self { unimplemented!() }
90/// # }
91/// #
92/// # impl core::ops::Neg for MyFancyNumberType {
93/// #   type Output = Self;
94/// #   fn neg(self) -> Self { unimplemented!() }
95/// # }
96/// #
97/// ```
98///
99pub trait RTreeNum: Bounded + Num + Clone + Copy + Signed + PartialOrd + Debug {}
100
101impl<S> RTreeNum for S where S: Bounded + Num + Clone + Copy + Signed + PartialOrd + Debug {}
102
103/// Defines a point type that is compatible with rstar.
104///
105/// This trait should be used for interoperability with other point types, not to define custom objects
106/// that can be inserted into r-trees. Use [`crate::RTreeObject`] or
107/// [`crate::primitives::GeomWithData`] instead.
108/// This trait defines points, not points with metadata.
109///
110/// `Point` is implemented out of the box for arrays like `[f32; 2]` or `[f64; 7]` (up to dimension 9)
111/// and for tuples like `(int, int)` and `(f64, f64, f64)` so tuples with only elements of the same type (up to dimension 9).
112///
113///
114/// # Implementation example
115/// Supporting a custom point type might look like this:
116///
117/// ```
118/// use rstar::Point;
119///
120/// #[derive(Copy, Clone, PartialEq, Debug)]
121/// struct IntegerPoint
122/// {
123///     x: i32,
124///     y: i32
125/// }
126///
127/// impl Point for IntegerPoint
128/// {
129///   type Scalar = i32;
130///   const DIMENSIONS: usize = 2;
131///
132///   fn generate(mut generator: impl FnMut(usize) -> Self::Scalar) -> Self
133///   {
134///     IntegerPoint {
135///       x: generator(0),
136///       y: generator(1)
137///     }
138///   }
139///
140///   fn nth(&self, index: usize) -> Self::Scalar
141///   {
142///     match index {
143///       0 => self.x,
144///       1 => self.y,
145///       _ => unreachable!()
146///     }
147///   }
148///
149///   fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar
150///   {
151///     match index {
152///       0 => &mut self.x,
153///       1 => &mut self.y,
154///       _ => unreachable!()
155///     }
156///   }
157/// }
158/// ```
159pub trait Point: Clone + PartialEq + Debug {
160    /// The number type used by this point type.
161    type Scalar: RTreeNum;
162
163    /// The number of dimensions of this point type.
164    const DIMENSIONS: usize;
165
166    /// Creates a new point value with given values for each dimension.
167    ///
168    /// The value that each dimension should be initialized with is given by the parameter `generator`.
169    /// Calling `generator(n)` returns the value of dimension `n`, `n` will be in the range `0 .. Self::DIMENSIONS`,
170    /// and will be called with values of `n` in ascending order.
171    fn generate(generator: impl FnMut(usize) -> Self::Scalar) -> Self;
172
173    /// Returns a single coordinate of this point.
174    ///
175    /// Returns the coordinate indicated by `index`. `index` is always smaller than `Self::DIMENSIONS`.
176    fn nth(&self, index: usize) -> Self::Scalar;
177
178    /// Mutable variant of [nth](#methods.nth).
179    fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar;
180}
181
182impl<T> PointExt for T where T: Point {}
183
184/// Utility functions for Point
185pub trait PointExt: Point {
186    /// Returns a new Point with all components set to zero.
187    fn new() -> Self {
188        Self::from_value(Zero::zero())
189    }
190
191    /// Applies `f` to each pair of components of `self` and `other`.
192    fn component_wise(
193        &self,
194        other: &Self,
195        mut f: impl FnMut(Self::Scalar, Self::Scalar) -> Self::Scalar,
196    ) -> Self {
197        Self::generate(|i| f(self.nth(i), other.nth(i)))
198    }
199
200    /// Returns whether all pairs of components of `self` and `other` pass test closure `f`. Short circuits if any result is false.
201    fn all_component_wise(
202        &self,
203        other: &Self,
204        mut f: impl FnMut(Self::Scalar, Self::Scalar) -> bool,
205    ) -> bool {
206        // TODO: Maybe do this by proper iteration
207        for i in 0..Self::DIMENSIONS {
208            if !f(self.nth(i), other.nth(i)) {
209                return false;
210            }
211        }
212        true
213    }
214
215    /// Returns the dot product of `self` and `rhs`.
216    fn dot(&self, rhs: &Self) -> Self::Scalar {
217        self.component_wise(rhs, |l, r| l * r)
218            .fold(Zero::zero(), |acc, val| acc + val)
219    }
220
221    /// Folds (aka reduces or injects) the Point component wise using `f` and returns the result.
222    /// fold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and the value of the current component.
223    /// The closure returns the value that the accumulator should have for the next iteration.
224    ///
225    /// The `start_value` is the value the accumulator will have on the first call of the closure.
226    ///
227    /// After applying the closure to every component of the Point, fold() returns the accumulator.
228    fn fold<T>(&self, start_value: T, mut f: impl FnMut(T, Self::Scalar) -> T) -> T {
229        let mut accumulated = start_value;
230        // TODO: Maybe do this by proper iteration
231        for i in 0..Self::DIMENSIONS {
232            accumulated = f(accumulated, self.nth(i));
233        }
234        accumulated
235    }
236
237    /// Returns a Point with every component set to `value`.
238    fn from_value(value: Self::Scalar) -> Self {
239        Self::generate(|_| value)
240    }
241
242    /// Returns a Point with each component set to the smallest of each component pair of `self` and `other`.
243    fn min_point(&self, other: &Self) -> Self {
244        self.component_wise(other, min_inline)
245    }
246
247    /// Returns a Point with each component set to the biggest of each component pair of `self` and `other`.
248    fn max_point(&self, other: &Self) -> Self {
249        self.component_wise(other, max_inline)
250    }
251
252    /// Returns the squared length of this Point as if it was a vector.
253    fn length_2(&self) -> Self::Scalar {
254        self.fold(Zero::zero(), |acc, cur| cur * cur + acc)
255    }
256
257    /// Substracts `other` from `self` component wise.
258    fn sub(&self, other: &Self) -> Self {
259        self.component_wise(other, |l, r| l - r)
260    }
261
262    /// Adds `other` to `self` component wise.
263    fn add(&self, other: &Self) -> Self {
264        self.component_wise(other, |l, r| l + r)
265    }
266
267    /// Multiplies `self` with `scalar` component wise.
268    fn mul(&self, scalar: Self::Scalar) -> Self {
269        self.map(|coordinate| coordinate * scalar)
270    }
271
272    /// Applies `f` to `self` component wise.
273    fn map(&self, mut f: impl FnMut(Self::Scalar) -> Self::Scalar) -> Self {
274        Self::generate(|i| f(self.nth(i)))
275    }
276
277    /// Returns the squared distance between `self` and `other`.
278    fn distance_2(&self, other: &Self) -> Self::Scalar {
279        self.sub(other).length_2()
280    }
281}
282
283#[inline]
284pub fn min_inline<S>(a: S, b: S) -> S
285where
286    S: RTreeNum,
287{
288    if a < b {
289        a
290    } else {
291        b
292    }
293}
294
295#[inline]
296pub fn max_inline<S>(a: S, b: S) -> S
297where
298    S: RTreeNum,
299{
300    if a > b {
301        a
302    } else {
303        b
304    }
305}
306
307macro_rules! count_exprs {
308    () => (0);
309    ($head:expr) => (1);
310    ($head:expr, $($tail:expr),*) => (1 + count_exprs!($($tail),*));
311}
312
313macro_rules! implement_point_for_array {
314    ($($index:expr),*) => {
315        impl<S> Point for [S; count_exprs!($($index),*)]
316        where
317            S: RTreeNum,
318        {
319            type Scalar = S;
320
321            const DIMENSIONS: usize = count_exprs!($($index),*);
322
323            fn generate(mut generator: impl FnMut(usize) -> S) -> Self
324            {
325                [$(generator($index)),*]
326            }
327
328            #[inline]
329            fn nth(&self, index: usize) -> Self::Scalar {
330                self[index]
331            }
332
333            #[inline]
334            fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
335                &mut self[index]
336            }
337        }
338    };
339}
340
341implement_point_for_array!(0, 1);
342implement_point_for_array!(0, 1, 2);
343implement_point_for_array!(0, 1, 2, 3);
344implement_point_for_array!(0, 1, 2, 3, 4);
345implement_point_for_array!(0, 1, 2, 3, 4, 5);
346implement_point_for_array!(0, 1, 2, 3, 4, 5, 6);
347implement_point_for_array!(0, 1, 2, 3, 4, 5, 6, 7);
348implement_point_for_array!(0, 1, 2, 3, 4, 5, 6, 7, 8);
349
350macro_rules! fixed_type {
351    ($expr:expr, $type:ty) => {
352        $type
353    };
354}
355
356macro_rules! impl_point_for_tuple {
357    ($($index:expr => $name:ident),+) => {
358        impl<S> Point for ($(fixed_type!($index, S),)+)
359        where
360            S: RTreeNum
361        {
362            type Scalar = S;
363
364            const DIMENSIONS: usize = count_exprs!($($index),*);
365
366            fn generate(mut generator: impl FnMut(usize) -> S) -> Self {
367                ($(generator($index),)+)
368            }
369
370            #[inline]
371            fn nth(&self, index: usize) -> Self::Scalar {
372                let ($($name,)+) = self;
373
374                match index {
375                    $($index => *$name,)+
376                    _ => unreachable!("index {} out of bounds for tuple", index),
377                }
378            }
379
380            #[inline]
381            fn nth_mut(&mut self, index: usize) -> &mut Self::Scalar {
382                let ($($name,)+) = self;
383
384                match index {
385                    $($index => $name,)+
386                    _ => unreachable!("index {} out of bounds for tuple", index),
387                }
388            }
389        }
390    };
391}
392
393impl_point_for_tuple!(0 => a);
394impl_point_for_tuple!(0 => a, 1 => b);
395impl_point_for_tuple!(0 => a, 1 => b, 2 => c);
396impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d);
397impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d, 4 => e);
398impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d, 4 => e, 5 => f);
399impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d, 4 => e, 5 => f, 6 => g);
400impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d, 4 => e, 5 => f, 6 => g, 7 => h);
401impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d, 4 => e, 5 => f, 6 => g, 7 => h, 8 => i);
402impl_point_for_tuple!(0 => a, 1 => b, 2 => c, 3 => d, 4 => e, 5 => f, 6 => g, 7 => h, 8 => i, 9 => j);
403
404#[cfg(test)]
405mod tests {
406    use super::*;
407
408    macro_rules! test_tuple_configuration {
409        ($($index:expr),*) => {
410            let a = ($($index),*);
411            $(assert_eq!(a.nth($index), $index));*
412        }
413    }
414
415    #[test]
416    fn test_tuples() {
417        // Test a couple of simple cases
418        let simple_int = (0, 1, 2);
419        assert_eq!(simple_int.nth(2), 2);
420        let simple_float = (0.5, 0.67, 1234.56);
421        assert_eq!(simple_float.nth(2), 1234.56);
422        let long_int = (0, 1, 2, 3, 4, 5, 6, 7, 8);
423        assert_eq!(long_int.nth(8), 8);
424
425        // Generate the code to test every nth function for every Tuple length
426        test_tuple_configuration!(0, 1);
427        test_tuple_configuration!(0, 1, 2);
428        test_tuple_configuration!(0, 1, 2, 3);
429        test_tuple_configuration!(0, 1, 2, 3, 4);
430        test_tuple_configuration!(0, 1, 2, 3, 4, 5);
431        test_tuple_configuration!(0, 1, 2, 3, 4, 5, 6);
432        test_tuple_configuration!(0, 1, 2, 3, 4, 5, 6, 7);
433        test_tuple_configuration!(0, 1, 2, 3, 4, 5, 6, 7, 8);
434    }
435}