1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
use std::{fmt::Debug, rc::Rc, sync::Arc};
use geo_types::Line;
use super::*;
use crate::GeoFloat;
/// Interface for types that can be processed to detect crossings.
///
/// This type is implemented by [`LineOrPoint`], but users may also implement
/// this on custom types to store extra information. Any type that represents an
/// ordered line-segment may implement this.
///
/// # Cloning
///
/// Note that for usage with the planar sweep iterators, the type must
/// also impl. `Clone`. If the custom type is not cheap to clone, use
/// either a reference to the type, a [`Rc`] or an [`Arc`]. All these
/// are supported via blanket trait implementations.
pub trait Cross: Sized + Debug {
/// Scalar used the coordinates.
type Scalar: GeoFloat;
/// The geometry associated with this type. Use a `Line` with the
/// `start` and `end` coordinates to represent a point.
fn line(&self) -> LineOrPoint<Self::Scalar>;
}
impl<'a, T: Cross> Cross for &'a T {
type Scalar = T::Scalar;
fn line(&self) -> LineOrPoint<Self::Scalar> {
T::line(*self)
}
}
impl<T: GeoFloat> Cross for LineOrPoint<T> {
type Scalar = T;
fn line(&self) -> LineOrPoint<Self::Scalar> {
*self
}
}
impl<T: GeoFloat> Cross for Line<T> {
type Scalar = T;
fn line(&self) -> LineOrPoint<Self::Scalar> {
(*self).into()
}
}
macro_rules! blanket_impl_smart_pointer {
($ty:ty) => {
impl<T: Cross> Cross for $ty {
type Scalar = T::Scalar;
fn line(&self) -> LineOrPoint<Self::Scalar> {
T::line(self)
}
}
};
}
blanket_impl_smart_pointer!(Box<T>);
blanket_impl_smart_pointer!(Rc<T>);
blanket_impl_smart_pointer!(Arc<T>);