1use either::Either;
4#[cfg(feature = "derive_serdes")]
5use serde;
6
7use crate::num_traits as num;
8use crate::types::{Affinity, Projectivity, Sign};
9
10pub trait ProjectiveSpace <S, V> : VectorSpace <S> where
12 V : VectorSpace <S> + std::fmt::Display,
13 S : Field + std::fmt::Display
14{
15 fn homography <A> (
17 affinity : Affinity <S, A, A, <A::Vector as Module <S>>::LinearEndo>
18 ) -> Projectivity <S, V, V, Self, Self, Self::LinearEndo> where
19 A : AffineSpace <S, Vector=V>;
20 fn homogeneous <A> (point_or_vector : Either <A::Point, A::Vector>) -> Self where
23 A : AffineSpace <S, Vector=V>,
24 V : GroupAction <A::Point>;
25}
26
27pub trait EuclideanSpace <S : Real> : AffineSpace <S> where
29 Self::Vector : InnerProductSpace <S>
30{
31 fn origin() -> Self::Point {
32 use num::Zero;
33 Self::Point::from_vector (Self::Vector::zero())
34 }
35}
36
37pub trait AffineSpace <S : Field> {
39 type Point : Point <Self::Vector>;
40 type Vector : VectorSpace <S> + GroupAction <Self::Point>;
41}
42
43impl <S, V> AffineSpace <S> for V where
44 S : Field,
45 V : VectorSpace <S> + GroupAction <V> + Point <V>
46{
47 type Point = Self;
48 type Vector = Self;
49}
50
51pub trait Point <V> : Sized + std::ops::Sub <Self, Output=V> where
54 V : AdditiveGroup + GroupAction <Self>
55{
56 fn to_vector (self) -> V;
57 fn from_vector (vector : V) -> Self;
58 fn origin() -> Self {
59 Self::from_vector (V::zero())
60 }
61}
62
63pub trait GroupAction <X> : Group {
65 fn action (self, x : X) -> X;
66}
67
68impl <G> GroupAction <G> for G where G : Group {
69 fn action (self, g : Self) -> Self {
70 Self::operation (g, self)
71 }
72}
73
74pub trait InnerProductSpace <S : Field> : VectorSpace <S> + Dot <S> {
76 fn inner_product (self, other : Self) -> S {
77 self.dot (other)
78 }
79}
80
81impl <V, S> NormedVectorSpace <S> for V where
82 V : InnerProductSpace <S>,
83 S : Field
84{
85 fn norm_squared (self) -> S {
86 self.self_dot()
87 }
88}
89
90pub trait Dot <S : Ring> : Module <S> {
92 fn dot (self, other : Self) -> S;
93 fn self_dot (self) -> S {
95 self.dot (self)
96 }
97}
98
99pub trait NormedVectorSpace <S : Field> : VectorSpace <S> {
101 fn norm_squared (self) -> S;
102 fn norm (self) -> S where S : Sqrt {
103 self.norm_squared().sqrt()
104 }
105 fn normalize (self) -> Self where S : Sqrt {
106 self / self.norm()
107 }
108 fn unit_sigvec (self) -> Self where S : SignedExt + Sqrt {
109 let v = self.sigvec();
110 if v.is_zero() {
111 v
112 } else {
113 v.normalize()
114 }
115 }
116}
117
118impl <V, S> MetricSpace <S> for V where
119 V : NormedVectorSpace <S>,
120 S : Field
121{
122 fn distance_squared (self, other : Self) -> S {
123 (self - other).norm_squared()
124 }
125}
126
127pub trait MetricSpace <S> : Sized {
129 fn distance_squared (self, other : Self) -> S;
130 fn distance (self, other : Self) -> S where S : Sqrt {
131 self.distance_squared (other).sqrt()
132 }
133}
134
135pub trait VectorSpace <S : Field> : Module <S> + std::ops::Div <S, Output=Self> + Copy {
137 fn map <F> (self, f : F) -> Self where F : FnMut (S) -> S;
139 fn sigvec (self) -> Self where S : SignedExt {
142 self.map (|x| x.signum_or_zero())
143 }
144}
145
146pub trait Module <S : Ring> : AdditiveGroup + std::ops::Mul <S, Output=Self> + Copy {
148 type LinearEndo : LinearMap <S, Self, Self> + MultiplicativeMonoid;
150}
151
152pub trait LinearMap <S, V, W> : std::ops::Mul <V, Output=W> + Copy where
154 S : Ring,
155 V : Module <S>,
156 W : Module <S>
157{
158 fn determinant (self) -> S;
159 fn transpose (self) -> Self;
160}
161
162pub trait Real : Field + SignedExt + Exp + Sqrt + Trig + MinMax {
164 fn pi() -> Self;
166 fn frac_pi_3() -> Self;
167 fn sqrt_3() -> Self;
168 fn frac_1_sqrt_3() -> Self;
169 fn floor (self) -> Self;
170 fn ceil (self) -> Self;
171 fn trunc (self) -> Self;
172 fn fract (self) -> Self;
173}
174
175pub trait Field : Ring + MultiplicativeGroup + Powi + Powf {
177 fn half() -> Self {
179 Self::one() / Self::two()
180 }
181 fn two() -> Self {
182 Self::one() + Self::one()
183 }
184 fn three() -> Self {
185 Self::one() + Self::one() + Self::one()
186 }
187 fn four() -> Self {
188 Self::two() * Self::two()
189 }
190 fn five() -> Self {
191 Self::two() + Self::three()
192 }
193 fn six() -> Self {
194 Self::two() * Self::three()
195 }
196 fn seven() -> Self {
197 Self::three() + Self::four()
198 }
199 fn eight() -> Self {
200 Self::two() * Self::two() * Self::two()
201 }
202 fn nine() -> Self {
203 Self::three() * Self::three()
204 }
205 fn ten() -> Self {
206 Self::two() * Self::five()
207 }
208}
209
210pub trait MultiplicativeGroup : MultiplicativeMonoid +
213 std::ops::Div <Self, Output=Self> + std::ops::DivAssign + num::Inv <Output=Self>
214{ }
215
216pub trait Integer : Ring + num::PrimInt + num::Signed { }
218
219pub trait Ring : Copy + PartialOrd + MinMax + AdditiveGroup +
222 std::ops::Mul <Self, Output=Self> + std::ops::MulAssign + num::Signed +
223 num::MulAdd <Self, Self, Output=Self> + num::MulAddAssign <Self, Self>
224{
225 fn squared (self) -> Self {
226 self * self
227 }
228 fn cubed (self) -> Self {
229 self * self * self
230 }
231}
232
233pub trait AdditiveGroup : AdditiveMonoid +
236 std::ops::Sub <Self, Output=Self> + std::ops::SubAssign + std::ops::Neg <Output=Self>
237{ }
238
239pub trait Group : PartialEq + std::ops::Neg <Output=Self> {
241 fn identity() -> Self;
242 fn operation (a : Self, b : Self) -> Self;
243}
244
245pub trait MultiplicativeMonoid : Sized + PartialEq +
248 std::ops::Mul <Self, Output=Self> + std::ops::MulAssign + num::One
249{ }
250
251pub trait AdditiveMonoid : Sized + PartialEq +
254 std::ops::Add <Self, Output=Self> + std::ops::AddAssign + num::Zero
255{ }
256
257pub trait Angle <S : Real> : Clone + Copy + PartialEq + PartialOrd + Sized +
259 AdditiveGroup + std::ops::Div <Self, Output=S> + std::ops::Mul <S, Output=Self> +
260 std::ops::Div <S, Output=Self> + std::ops::Rem <Self, Output=Self>
261{
262 fn full_turn() -> Self;
265 fn half_turn() -> Self {
268 Self::full_turn() / S::two()
269 }
270 fn wrap_signed (self) -> Self {
272 let out = (self + Self::half_turn()).wrap_unsigned() - Self::half_turn();
273 if out == -Self::half_turn() {
274 Self::half_turn()
275 } else {
276 out
277 }
278 }
279 fn wrap_unsigned (self) -> Self {
281 if self >= Self::full_turn() {
282 self % Self::full_turn()
283 } else if self < Self::zero() {
284 self + Self::full_turn() * ((self / Self::full_turn()).trunc().abs() + S::one())
285 } else {
286 self
287 }
288 }
289}
290
291pub trait Pow {
293 fn pow (self, exp : u32) -> Self;
294}
295pub trait Powi {
297 fn powi (self, n : i32) -> Self;
298}
299pub trait Powf {
301 fn powf (self, n : Self) -> Self;
302}
303pub trait Exp {
305 fn exp (self) -> Self;
306}
307pub trait Sqrt {
309 fn sqrt (self) -> Self;
310}
311pub trait Trig : Sized {
313 fn sin (self) -> Self;
314 fn sin_cos (self) -> (Self, Self);
315 fn cos (self) -> Self;
316 fn tan (self) -> Self;
317 fn asin (self) -> Self;
318 fn acos (self) -> Self;
319 fn atan (self) -> Self;
320 fn atan2 (self, other : Self) -> Self;
321}
322
323pub trait MinMax {
327 fn min (self, other : Self) -> Self;
328 fn max (self, other : Self) -> Self;
329 fn clamp (self, min : Self, max : Self) -> Self;
330}
331
332pub trait SignedExt : num::Signed {
334 #[inline]
335 fn sign (self) -> Sign {
336 if self.is_zero() {
337 Sign::Zero
338 } else if self.is_positive() {
339 Sign::Positive
340 } else {
341 debug_assert!(self.is_negative());
342 Sign::Negative
343 }
344 }
345 #[inline]
348 fn signum_or_zero (self) -> Self where Self : num::Zero {
349 if self.is_zero() {
350 Self::zero()
351 } else {
352 self.signum()
353 }
354 }
355}
356
357#[cfg(not(feature = "derive_serdes"))]
362pub trait MaybeSerDes { }
363#[cfg(feature = "derive_serdes")]
364pub trait MaybeSerDes : serde::Serialize + serde::de::DeserializeOwned { }
365
366impl <
367 #[cfg(not(feature = "derive_serdes"))]
368 T,
369 #[cfg(feature = "derive_serdes")]
370 T : serde::Serialize + serde::de::DeserializeOwned
371> MaybeSerDes for T { }
372
373macro impl_integer ($type:ty) {
374 impl Integer for $type { }
375 impl Ring for $type { }
376 impl AdditiveGroup for $type { }
377 impl AdditiveMonoid for $type { }
378 impl SignedExt for $type { }
379 impl MinMax for $type {
380 fn min (self, other : Self) -> Self {
381 Ord::min (self, other)
382 }
383 fn max (self, other : Self) -> Self {
384 Ord::max (self, other)
385 }
386 fn clamp (self, min : Self, max : Self) -> Self {
387 Ord::clamp (self, min, max)
388 }
389 }
390 impl Pow for $type {
391 fn pow (self, exp : u32) -> Self {
392 self.pow (exp)
393 }
394 }
395}
396impl_integer!(i8);
397impl_integer!(i16);
398impl_integer!(i32);
399impl_integer!(i64);
400
401macro impl_real_float ($type:ident) {
402 impl VectorSpace <Self> for $type {
403 fn map <F> (self, mut f : F) -> Self where F : FnMut (Self) -> Self {
404 f (self)
405 }
406 }
407 impl Module <Self> for $type {
408 type LinearEndo = Self;
409 }
410 impl LinearMap <Self, Self, Self> for $type {
411 fn determinant (self) -> Self {
412 self
413 }
414 fn transpose (self) -> Self {
415 self
416 }
417 }
418 impl Real for $type {
419 fn pi() -> Self {
420 std::$type::consts::PI
421 }
422 fn frac_pi_3() -> Self {
423 std::$type::consts::FRAC_PI_3
424 }
425 #[allow(clippy::excessive_precision)]
426 fn sqrt_3() -> Self {
427 1.732050807568877293527446341505872366942805253810380628055f64 as $type
428 }
429 #[allow(clippy::excessive_precision)]
430 fn frac_1_sqrt_3() -> Self {
431 (1.0f64 / 1.732050807568877293527446341505872366942805253810380628055f64) as $type
432 }
433 fn floor (self) -> Self {
434 self.floor()
435 }
436 fn ceil (self) -> Self {
437 self.ceil()
438 }
439 fn trunc (self) -> Self {
440 self.trunc()
441 }
442 fn fract (self) -> Self {
443 self.fract()
444 }
445 }
446 impl Field for $type { }
447 impl MultiplicativeGroup for $type { }
448 impl MultiplicativeMonoid for $type { }
449 impl Ring for $type { }
450 impl AdditiveGroup for $type { }
451 impl AdditiveMonoid for $type { }
452 impl SignedExt for $type { }
453 impl MinMax for $type {
454 fn min (self, other : Self) -> Self {
455 self.min (other)
456 }
457 fn max (self, other : Self) -> Self {
458 self.max (other)
459 }
460 fn clamp (self, min : Self, max : Self) -> Self {
461 self.clamp (min, max)
462 }
463 }
464 impl Powi for $type {
465 fn powi (self, n : i32) -> Self {
466 self.powi (n as i32)
467 }
468 }
469 impl Powf for $type {
470 fn powf (self, n : Self) -> Self {
471 self.powf (n)
472 }
473 }
474 impl Exp for $type {
475 fn exp (self) -> Self {
476 self.exp()
477 }
478 }
479 impl Sqrt for $type {
480 fn sqrt (self) -> Self {
481 self.sqrt()
482 }
483 }
484 impl Trig for $type {
485 fn sin (self) -> Self {
486 self.sin()
487 }
488 fn sin_cos (self) -> (Self, Self) {
489 self.sin_cos()
490 }
491 fn cos (self) -> Self {
492 self.cos()
493 }
494 fn tan (self) -> Self {
495 self.tan()
496 }
497 fn asin (self) -> Self {
498 self.asin()
499 }
500 fn acos (self) -> Self {
501 self.acos()
502 }
503 fn atan (self) -> Self {
504 self.atan()
505 }
506 fn atan2 (self, other : Self) -> Self {
507 self.atan2 (other)
508 }
509 }
510}
511
512impl_real_float!(f32);
513impl_real_float!(f64);