1#![doc(
9 html_favicon_url = "https://raw.githubusercontent.com/olson-sean-k/theon/master/doc/theon-favicon.ico"
10)]
11#![doc(
12 html_logo_url = "https://raw.githubusercontent.com/olson-sean-k/theon/master/doc/theon.svg?sanitize=true"
13)]
14
15pub mod adjunct;
16pub mod lapack;
17pub mod ops;
18pub mod query;
19pub mod space;
20
21mod integration;
22
23use decorum::R64;
24use num_traits::cast::NumCast;
25use num_traits::identities::{One, Zero};
26use num_traits::Num;
27
28use crate::space::EuclideanSpace;
29
30pub mod prelude {
31 pub use crate::query::Intersection as _;
34}
35
36pub type Position<T> = <T as AsPosition>::Position;
37
38pub trait AsPosition {
68 type Position: EuclideanSpace;
69
70 fn as_position(&self) -> &Self::Position;
71}
72
73pub trait AsPositionMut: AsPosition {
109 fn as_position_mut(&mut self) -> &mut Self::Position;
110
111 fn transform<F>(&mut self, mut f: F)
112 where
113 F: FnMut(&Self::Position) -> Self::Position,
114 {
115 *self.as_position_mut() = f(self.as_position());
116 }
117
118 fn map_position<F>(mut self, f: F) -> Self
119 where
120 Self: Sized,
121 F: FnMut(&Self::Position) -> Self::Position,
122 {
123 self.transform(f);
124 self
125 }
126}
127
128impl<T> AsPosition for &'_ T
129where
130 T: AsPosition,
131 T::Position: EuclideanSpace,
132{
133 type Position = <T as AsPosition>::Position;
134
135 fn as_position(&self) -> &Self::Position {
136 T::as_position(self)
137 }
138}
139
140impl<T> AsPosition for &'_ mut T
141where
142 T: AsPosition,
143 T::Position: EuclideanSpace,
144{
145 type Position = <T as AsPosition>::Position;
146
147 fn as_position(&self) -> &Self::Position {
148 T::as_position(self)
149 }
150}
151
152impl<T> AsPositionMut for &'_ mut T
153where
154 T: AsPositionMut,
155{
156 fn as_position_mut(&mut self) -> &mut Self::Position {
157 T::as_position_mut(self)
158 }
159}
160
161pub fn lerp<T>(a: T, b: T, f: R64) -> T
163where
164 T: Num + NumCast,
165{
166 let f = num_traits::clamp(f, Zero::zero(), One::one());
167 let af = <R64 as NumCast>::from(a).unwrap() * (R64::one() - f);
168 let bf = <R64 as NumCast>::from(b).unwrap() * f;
169 <T as NumCast>::from(af + bf).unwrap()
170}