vector_space/
lib.rs

1#![no_std]
2#![deny(missing_docs)]
3/*!
4This crate contains traits for working with vector spaces.
5
6You can also define some library in terms of these traits instead of using a specific vector math implementation, so the user can choose, which one to use, or simply add multiple vector math libraries which implement these traits yourself by using this library.
7**/
8
9use core::{
10    cmp::PartialOrd,
11    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
12};
13use num_traits::{Zero, real::Real};
14
15/// This trait specifies some type to be a vector type.
16/// It specifies the scalar type and is required for other vector types.
17pub trait VectorSpace: Zero + PartialEq
18where
19    Self: Add<Output = Self>
20        + Sub<Output = Self>
21        + Mul<<Self as VectorSpace>::Scalar, Output = Self>
22        + Div<<Self as VectorSpace>::Scalar, Output = Self>
23        + Neg<Output = Self>,
24{
25    /// The scalar type of the vector space.
26    type Scalar: Real + PartialOrd;
27}
28
29impl VectorSpace for f32 {
30    type Scalar = Self;
31}
32impl VectorSpace for f64 {
33    type Scalar = Self;
34}
35
36/// This trait is automatically implemented for vector spaces, which also implement assignment operations.
37pub trait VectorSpaceAssign:
38    VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
39{
40}
41impl<T> VectorSpaceAssign for T where
42    T: VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
43{
44}
45
46/// Marker trait for affine spaces, types whose differences are vectors.
47pub trait AffineSpace: Sub<Output = Self::Diff> + Sized {
48    /// The difference type.
49    type Diff: VectorSpace;
50}
51
52impl<T, D> AffineSpace for T
53where
54    T: Sub<Output = D>,
55    D: VectorSpace,
56{
57    type Diff = D;
58}
59
60/// Linear interpolation of two points.
61#[inline]
62pub fn interpolate<T>(a: T, b: T, ratio: <T::Diff as VectorSpace>::Scalar) -> T
63where
64    T: Clone + AffineSpace + Add<T::Diff, Output = T>,
65{
66    a.clone() + (b - a) * ratio
67}