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>)
23 -> Self
24 where
25 A : AffineSpace <S, Vector=V>,
26 V : GroupAction <A::Point>;
27}
28
29pub trait EuclideanSpace <S : Real> : AffineSpace <S> where
31 Self::Vector : InnerProductSpace <S>
32{
33 fn origin() -> Self::Point {
34 use num::Zero;
35 Self::Point::from_vector (Self::Vector::zero())
36 }
37}
38
39pub trait AffineSpace <S : Field> {
41 type Point : Point <Self::Vector>;
42 type Vector : VectorSpace <S> + GroupAction <Self::Point>;
43}
44
45impl <S, V> AffineSpace <S> for V where
46 S : Field,
47 V : VectorSpace <S> + GroupAction <V> + Point <V>
48{
49 type Point = Self;
50 type Vector = Self;
51}
52
53pub trait Point <V> : Sized + std::ops::Sub <Self, Output=V> where
56 V : AdditiveGroup + GroupAction <Self>
57{
58 fn to_vector (self) -> V;
59 fn from_vector (vector : V) -> Self;
60 fn origin() -> Self {
61 Self::from_vector (V::zero())
62 }
63}
64
65pub trait GroupAction <X> : Group {
67 fn action (self, x : X) -> X;
68}
69
70impl <G> GroupAction <G> for G where G : Group {
71 fn action (self, g : Self) -> Self {
72 Self::operation (g, self)
73 }
74}
75
76pub trait InnerProductSpace <S : Field> : VectorSpace <S> + Dot <S> {
78 fn inner_product (self, other : Self) -> S {
79 self.dot (other)
80 }
81}
82
83impl <V, S> NormedVectorSpace <S> for V where
84 V : InnerProductSpace <S>,
85 S : Field
86{
87 fn norm_squared (self) -> S {
88 self.self_dot()
89 }
90}
91
92pub trait Dot <S : Ring> : Module <S> {
94 fn dot (self, other : Self) -> S;
95 fn self_dot (self) -> S {
97 self.dot (self)
98 }
99}
100
101pub trait NormedVectorSpace <S : Field> : VectorSpace <S> {
103 fn norm_squared (self) -> S;
104 fn norm (self) -> S where S : Sqrt {
105 self.norm_squared().sqrt()
106 }
107 fn normalize (self) -> Self where S : Sqrt {
108 self / self.norm()
109 }
110 fn unit_sigvec (self) -> Self where S : SignedExt + Sqrt {
111 let v = self.sigvec();
112 if v.is_zero() {
113 v
114 } else {
115 v.normalize()
116 }
117 }
118}
119
120impl <V, S> MetricSpace <S> for V where
121 V : NormedVectorSpace <S>,
122 S : Field
123{
124 fn distance_squared (self, other : Self) -> S {
125 (self - other).norm_squared()
126 }
127}
128
129pub trait MetricSpace <S> : Sized {
131 fn distance_squared (self, other : Self) -> S;
132 fn distance (self, other : Self) -> S where S : Sqrt {
133 self.distance_squared (other).sqrt()
134 }
135}
136
137pub trait VectorSpace <S : Field> :
139 Module <S> + std::ops::Div <S, Output=Self> + Copy
140{
141 fn map <F> (self, f : F) -> Self where F : FnMut (S) -> S;
143 fn sigvec (self) -> Self where S : SignedExt {
146 self.map (|x| x.signum_or_zero())
147 }
148}
149
150pub trait Module <S : Ring> :
152 AdditiveGroup + std::ops::Mul <S, Output=Self> + Copy
153{
154 type LinearEndo : LinearMap <S, Self, Self> + MultiplicativeMonoid;
156}
157
158pub trait LinearMap <S, V, W> : std::ops::Mul <V, Output=W> + Copy where
160 S : Ring,
161 V : Module <S>,
162 W : Module <S>
163{
164 fn determinant (self) -> S;
165 fn transpose (self) -> Self;
166}
167
168pub trait Real : Field + SignedExt + Exp + Sqrt + Trig + MinMax {
170 fn pi() -> Self;
172 fn frac_pi_3() -> Self;
173 fn sqrt_3() -> Self;
174 fn frac_1_sqrt_3() -> Self;
175 fn floor (self) -> Self;
176 fn ceil (self) -> Self;
177 fn trunc (self) -> Self;
178 fn fract (self) -> Self;
179}
180
181pub trait Field : Ring + MultiplicativeGroup + Powi + Powf {
184 fn half() -> Self {
186 Self::one() / Self::two()
187 }
188 fn two() -> Self {
189 Self::one() + Self::one()
190 }
191 fn three() -> Self {
192 Self::one() + Self::one() + Self::one()
193 }
194 fn four() -> Self {
195 Self::two() * Self::two()
196 }
197 fn five() -> Self {
198 Self::two() + Self::three()
199 }
200 fn six() -> Self {
201 Self::two() * Self::three()
202 }
203 fn seven() -> Self {
204 Self::three() + Self::four()
205 }
206 fn eight() -> Self {
207 Self::two() * Self::two() * Self::two()
208 }
209 fn nine() -> Self {
210 Self::three() * Self::three()
211 }
212 fn ten() -> Self {
213 Self::two() * Self::five()
214 }
215}
216
217pub trait MultiplicativeGroup : MultiplicativeMonoid +
220 std::ops::Div <Self, Output=Self> + std::ops::DivAssign +
221 num::Inv <Output=Self>
222{ }
223
224pub trait Integer : Ring + num::PrimInt + num::Signed { }
226
227pub trait Ring : Copy + PartialOrd + MinMax + AdditiveGroup +
230 std::ops::Mul <Self, Output=Self> + std::ops::MulAssign + num::Signed +
231 num::MulAdd <Self, Self, Output=Self> + num::MulAddAssign <Self, Self>
232{
233 fn squared (self) -> Self {
234 self * self
235 }
236 fn cubed (self) -> Self {
237 self * self * self
238 }
239}
240
241pub trait AdditiveGroup : AdditiveMonoid +
244 std::ops::Sub <Self, Output=Self> + std::ops::SubAssign +
245 std::ops::Neg <Output=Self>
246{ }
247
248pub trait Group : PartialEq + std::ops::Neg <Output=Self> {
250 fn identity() -> Self;
251 fn operation (a : Self, b : Self) -> Self;
252}
253
254pub trait MultiplicativeMonoid : Sized + PartialEq +
257 std::ops::Mul <Self, Output=Self> + std::ops::MulAssign + num::One
258{ }
259
260pub trait AdditiveMonoid : Sized + PartialEq +
263 std::ops::Add <Self, Output=Self> + std::ops::AddAssign + num::Zero
264{ }
265
266pub trait Angle <S : Real> : Clone + Copy + PartialEq + PartialOrd + Sized +
268 AdditiveGroup + std::ops::Div <Self, Output=S> +
269 std::ops::Mul <S, Output=Self> + std::ops::Div <S, Output=Self> +
270 std::ops::Rem <Self, Output=Self>
271{
272 fn full_turn() -> Self;
275 fn half_turn() -> Self {
278 Self::full_turn() / S::two()
279 }
280 fn wrap_signed (self) -> Self {
282 let out = (self + Self::half_turn()).wrap_unsigned() - Self::half_turn();
283 if out == -Self::half_turn() {
284 Self::half_turn()
285 } else {
286 out
287 }
288 }
289 fn wrap_unsigned (self) -> Self {
291 if self >= Self::full_turn() {
292 self % Self::full_turn()
293 } else if self < Self::zero() {
294 self + Self::full_turn() *
295 ((self / Self::full_turn()).trunc().abs() + S::one())
296 } else {
297 self
298 }
299 }
300}
301
302pub trait Pow {
304 fn pow (self, exp : u32) -> Self;
305}
306pub trait Powi {
308 fn powi (self, n : i32) -> Self;
309}
310pub trait Powf {
312 fn powf (self, n : Self) -> Self;
313}
314pub trait Exp {
316 fn exp (self) -> Self;
317}
318pub trait Sqrt {
320 fn sqrt (self) -> Self;
321}
322pub trait Trig : Sized {
324 fn sin (self) -> Self;
325 fn sin_cos (self) -> (Self, Self);
326 fn cos (self) -> Self;
327 fn tan (self) -> Self;
328 fn asin (self) -> Self;
329 fn acos (self) -> Self;
330 fn atan (self) -> Self;
331 fn atan2 (self, other : Self) -> Self;
332}
333
334pub trait MinMax {
339 fn min (self, other : Self) -> Self;
340 fn max (self, other : Self) -> Self;
341 fn clamp (self, min : Self, max : Self) -> Self;
342}
343
344pub trait SignedExt : num::Signed {
346 #[inline]
347 fn sign (self) -> Sign {
348 if self.is_zero() {
349 Sign::Zero
350 } else if self.is_positive() {
351 Sign::Positive
352 } else {
353 debug_assert!(self.is_negative());
354 Sign::Negative
355 }
356 }
357 #[inline]
360 fn signum_or_zero (self) -> Self where Self : num::Zero {
361 if self.is_zero() {
362 Self::zero()
363 } else {
364 self.signum()
365 }
366 }
367}
368
369#[cfg(not(feature = "derive_serdes"))]
374pub trait MaybeSerDes { }
375#[cfg(feature = "derive_serdes")]
376pub trait MaybeSerDes : serde::Serialize + serde::de::DeserializeOwned { }
377
378impl <
379 #[cfg(not(feature = "derive_serdes"))]
380 T,
381 #[cfg(feature = "derive_serdes")]
382 T : serde::Serialize + serde::de::DeserializeOwned
383> MaybeSerDes for T { }
384
385macro impl_integer ($type:ty) {
386 impl Integer for $type { }
387 impl Ring for $type { }
388 impl AdditiveGroup for $type { }
389 impl AdditiveMonoid for $type { }
390 impl SignedExt for $type { }
391 impl MinMax for $type {
392 fn min (self, other : Self) -> Self {
393 Ord::min (self, other)
394 }
395 fn max (self, other : Self) -> Self {
396 Ord::max (self, other)
397 }
398 fn clamp (self, min : Self, max : Self) -> Self {
399 Ord::clamp (self, min, max)
400 }
401 }
402 impl Pow for $type {
403 fn pow (self, exp : u32) -> Self {
404 self.pow (exp)
405 }
406 }
407}
408impl_integer!(i8);
409impl_integer!(i16);
410impl_integer!(i32);
411impl_integer!(i64);
412
413macro impl_real_float ($type:ident) {
414 impl VectorSpace <Self> for $type {
415 fn map <F> (self, mut f : F) -> Self where F : FnMut (Self) -> Self {
416 f (self)
417 }
418 }
419 impl Module <Self> for $type {
420 type LinearEndo = Self;
421 }
422 impl LinearMap <Self, Self, Self> for $type {
423 fn determinant (self) -> Self {
424 self
425 }
426 fn transpose (self) -> Self {
427 self
428 }
429 }
430 impl Real for $type {
431 fn pi() -> Self {
432 std::$type::consts::PI
433 }
434 fn frac_pi_3() -> Self {
435 std::$type::consts::FRAC_PI_3
436 }
437 #[allow(clippy::excessive_precision)]
438 fn sqrt_3() -> Self {
439 1.732050807568877293527446341505872366942805253810380628055f64 as $type
440 }
441 #[allow(clippy::excessive_precision)]
442 fn frac_1_sqrt_3() -> Self {
443 (1.0f64 / 1.732050807568877293527446341505872366942805253810380628055f64) as $type
444 }
445 fn floor (self) -> Self {
446 self.floor()
447 }
448 fn ceil (self) -> Self {
449 self.ceil()
450 }
451 fn trunc (self) -> Self {
452 self.trunc()
453 }
454 fn fract (self) -> Self {
455 self.fract()
456 }
457 }
458 impl Field for $type { }
459 impl MultiplicativeGroup for $type { }
460 impl MultiplicativeMonoid for $type { }
461 impl Ring for $type { }
462 impl AdditiveGroup for $type { }
463 impl AdditiveMonoid for $type { }
464 impl SignedExt for $type { }
465 impl MinMax for $type {
466 fn min (self, other : Self) -> Self {
467 self.min (other)
468 }
469 fn max (self, other : Self) -> Self {
470 self.max (other)
471 }
472 fn clamp (self, min : Self, max : Self) -> Self {
473 self.clamp (min, max)
474 }
475 }
476 impl Powi for $type {
477 fn powi (self, n : i32) -> Self {
478 self.powi (n as i32)
479 }
480 }
481 impl Powf for $type {
482 fn powf (self, n : Self) -> Self {
483 self.powf (n)
484 }
485 }
486 impl Exp for $type {
487 fn exp (self) -> Self {
488 self.exp()
489 }
490 }
491 impl Sqrt for $type {
492 fn sqrt (self) -> Self {
493 self.sqrt()
494 }
495 }
496 impl Trig for $type {
497 fn sin (self) -> Self {
498 self.sin()
499 }
500 fn sin_cos (self) -> (Self, Self) {
501 self.sin_cos()
502 }
503 fn cos (self) -> Self {
504 self.cos()
505 }
506 fn tan (self) -> Self {
507 self.tan()
508 }
509 fn asin (self) -> Self {
510 self.asin()
511 }
512 fn acos (self) -> Self {
513 self.acos()
514 }
515 fn atan (self) -> Self {
516 self.atan()
517 }
518 fn atan2 (self, other : Self) -> Self {
519 self.atan2 (other)
520 }
521 }
522}
523
524impl_real_float!(f32);
525impl_real_float!(f64);