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 67 68 69 70 71 72 73 74 75 76 77 78 79
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
use core::ops::{Add, Mul};
use num_traits::real::Real;
/// All elements in a quasi metric space should implement this trait.
///
/// If the struct implementing this trait also implements `Topology`,
/// the `distance(to)` method should be equivalent to `self.shortest_path(to).length()`.
pub trait QuasiMetric<T = f64> {
/// Returns the length of the shortest path between the two points.
fn distance(self, to: Self) -> T;
}
/// Trait for elements having a length.
pub trait Length<T = f64> {
/// Returns the length of the element.
fn length(&self) -> T;
}
/// The merge trait is used to merge two elements together.
///
/// Often this is a linear interpolation between two elements.
/// In the case of Quaternions it is a spherical linear interpolation.
///
/// A default implementation of this trait is provided for all `E` that
/// are `Add<Output = E> + Mul<T, Output = E> + Copy` as these
/// operations let us assume that the elements live in a vector-like space.
///
/// If the struct implementing this trait also implements `Topology`,
/// the `merge(factor)` method should be equivalent to `self.shortest_path(to).contract(factor)`.
pub trait Merge<T = f64> {
/// Merge between `self` and `to` using `factor`.
///
/// This can be thought of creating a point on (one of) the shortest Paths
/// between the two given points.
///
/// Merging `self` with a factor of `Zero` should return a copy of `self`.
/// Merging `to` with a factor of `One` should return a copy of `to`.
/// It is assumed that the factor decides how similar the result will be to either
/// `self` or `to`.
fn merge(self, to: Self, factor: T) -> Self;
}
/// Trait for structures containing two elements which can be merged together.
pub trait Connected<P, T = f64> {
/// Returns the merged point of the start point and end point inside `self` with weight `factor`.
///
/// Contracting with a factor of `Zero` should return the start point.
/// Contracting with a factor of `One` should return the end point.
/// The factor decides how similar the result will be to the start or end point.
fn contract(&self, factor: T) -> P;
}
/// Main trait for topological spaces.
///
/// The associated type `Path` should implement as many traits as possible which allows to implement
/// other traits trivially.
/// - Length -> QuasiMetric
/// - Merge -> Connected
pub trait Topology {
/// The type of paths in this space. Usually \[Self,Self\].
type Path;
/// Function which returns the shortest path between `self` as start point and `to` as end point.
///
/// Often this returns a line are something equivalent from `self` to `to`.
fn shortest_path(self, to: Self) -> Self::Path;
}
impl<E, T> Merge<T> for E
where
E: Add<Output = E> + Mul<T, Output = E> + Copy,
T: Real,
{
fn merge(self, other: Self, factor: T) -> E {
self * (T::one() - factor) + other * factor
}
}