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 {
186 fn two() -> Self {
188 Self::one() + Self::one()
189 }
190 fn three() -> Self {
191 Self::one() + Self::one() + Self::one()
192 }
193 fn four() -> Self {
194 Self::two() * Self::two()
195 }
196 fn five() -> Self {
197 Self::two() + Self::three()
198 }
199 fn six() -> Self {
200 Self::two() * Self::three()
201 }
202 fn seven() -> Self {
203 Self::three() + Self::four()
204 }
205 fn eight() -> Self {
206 Self::two() * Self::two() * Self::two()
207 }
208 fn nine() -> Self {
209 Self::three() * Self::three()
210 }
211 fn ten() -> Self {
212 Self::two() * Self::five()
213 }
214}
215
216pub trait MultiplicativeGroup : MultiplicativeMonoid +
219 std::ops::Div <Self, Output=Self> + std::ops::DivAssign +
220 num::Inv <Output=Self>
221{ }
222
223pub trait Integer : Ring + num::PrimInt + num::Signed { }
225
226pub trait Ring : Copy + PartialOrd + MinMax + AdditiveGroup +
229 std::ops::Mul <Self, Output=Self> + std::ops::MulAssign + num::Signed +
230 num::MulAdd <Self, Self, Output=Self> + num::MulAddAssign <Self, Self>
231{ }
232
233pub trait AdditiveGroup : AdditiveMonoid +
236 std::ops::Sub <Self, Output=Self> + std::ops::SubAssign +
237 std::ops::Neg <Output=Self>
238{ }
239
240pub trait Group : PartialEq + std::ops::Neg <Output=Self> {
242 fn identity() -> Self;
243 fn operation (a : Self, b : Self) -> Self;
244}
245
246pub trait MultiplicativeMonoid : Sized + PartialEq +
249 std::ops::Mul <Self, Output=Self> + std::ops::MulAssign + num::One
250{ }
251
252pub trait AdditiveMonoid : Sized + PartialEq +
255 std::ops::Add <Self, Output=Self> + std::ops::AddAssign + num::Zero
256{ }
257
258pub trait Angle <S : Real> : Clone + Copy + PartialEq + PartialOrd + Sized +
260 AdditiveGroup + std::ops::Div <Self, Output=S> +
261 std::ops::Mul <S, Output=Self> + std::ops::Div <S, Output=Self> +
262 std::ops::Rem <Self, Output=Self>
263{
264 fn full_turn() -> Self;
267 fn half_turn() -> Self {
270 Self::full_turn() / S::two()
271 }
272 fn wrap_signed (self) -> Self {
274 let out = (self + Self::half_turn()).wrap_unsigned() - Self::half_turn();
275 if out == -Self::half_turn() {
276 Self::half_turn()
277 } else {
278 out
279 }
280 }
281 fn wrap_unsigned (self) -> Self {
283 if self >= Self::full_turn() {
284 self % Self::full_turn()
285 } else if self < Self::zero() {
286 self + Self::full_turn() *
287 ((self / Self::full_turn()).trunc().abs() + S::one())
288 } else {
289 self
290 }
291 }
292}
293
294pub trait Sqrt {
296 fn sqrt (self) -> Self;
297}
298pub trait Exp {
300 fn exp (self) -> Self;
301}
302pub trait Trig : Sized {
304 fn sin (self) -> Self;
305 fn sin_cos (self) -> (Self, Self);
306 fn cos (self) -> Self;
307 fn tan (self) -> Self;
308 fn asin (self) -> Self;
309 fn acos (self) -> Self;
310 fn atan (self) -> Self;
311 fn atan2 (self, other : Self) -> Self;
312}
313
314pub trait MinMax {
319 fn min (self, other : Self) -> Self;
320 fn max (self, other : Self) -> Self;
321 fn clamp (self, min : Self, max : Self) -> Self;
322}
323
324pub trait SignedExt : num::Signed {
326 #[inline]
327 fn sign (self) -> Sign {
328 if self.is_zero() {
329 Sign::Zero
330 } else if self.is_positive() {
331 Sign::Positive
332 } else {
333 debug_assert!(self.is_negative());
334 Sign::Negative
335 }
336 }
337 #[inline]
340 fn signum_or_zero (self) -> Self where Self : num::Zero {
341 if self.is_zero() {
342 Self::zero()
343 } else {
344 self.signum()
345 }
346 }
347}
348
349#[cfg(not(feature = "derive_serdes"))]
354pub trait MaybeSerDes { }
355#[cfg(feature = "derive_serdes")]
356pub trait MaybeSerDes : serde::Serialize + serde::de::DeserializeOwned { }
357
358impl <
359 #[cfg(not(feature = "derive_serdes"))]
360 T,
361 #[cfg(feature = "derive_serdes")]
362 T : serde::Serialize + serde::de::DeserializeOwned
363> MaybeSerDes for T { }
364
365macro impl_integer ($type:ty) {
366 impl Integer for $type { }
367 impl Ring for $type { }
368 impl AdditiveGroup for $type { }
369 impl AdditiveMonoid for $type { }
370 impl SignedExt for $type { }
371 impl MinMax for $type {
372 fn min (self, other : Self) -> Self {
373 Ord::min (self, other)
374 }
375 fn max (self, other : Self) -> Self {
376 Ord::max (self, other)
377 }
378 fn clamp (self, min : Self, max : Self) -> Self {
379 Ord::clamp (self, min, max)
380 }
381 }
382}
383impl_integer!(i8);
384impl_integer!(i16);
385impl_integer!(i32);
386impl_integer!(i64);
387
388macro impl_real_float ($type:ident) {
389 impl VectorSpace <Self> for $type {
390 fn map <F> (self, mut f : F) -> Self where F : FnMut (Self) -> Self {
391 f (self)
392 }
393 }
394 impl Module <Self> for $type {
395 type LinearEndo = Self;
396 }
397 impl LinearMap <Self, Self, Self> for $type {
398 fn determinant (self) -> Self {
399 self
400 }
401 fn transpose (self) -> Self {
402 self
403 }
404 }
405 impl Real for $type {
406 fn pi() -> Self {
407 std::$type::consts::PI
408 }
409 fn frac_pi_3() -> Self {
410 std::$type::consts::FRAC_PI_3
411 }
412 fn sqrt_3() -> Self {
413 1.732050807568877293527446341505872366942805253810380628055f64 as $type
414 }
415 fn frac_1_sqrt_3() -> Self {
416 (1.0f64 / 1.732050807568877293527446341505872366942805253810380628055f64)
417 as $type
418 }
419 fn floor (self) -> Self {
420 self.floor()
421 }
422 fn ceil (self) -> Self {
423 self.ceil()
424 }
425 fn trunc (self) -> Self {
426 self.trunc()
427 }
428 fn fract (self) -> Self {
429 self.fract()
430 }
431 }
432 impl Field for $type { }
433 impl MultiplicativeGroup for $type { }
434 impl MultiplicativeMonoid for $type { }
435 impl Ring for $type { }
436 impl AdditiveGroup for $type { }
437 impl AdditiveMonoid for $type { }
438 impl SignedExt for $type { }
439 impl MinMax for $type {
440 fn min (self, other : Self) -> Self {
441 self.min (other)
442 }
443 fn max (self, other : Self) -> Self {
444 self.max (other)
445 }
446 fn clamp (self, min : Self, max : Self) -> Self {
447 self.clamp (min, max)
448 }
449 }
450 impl Exp for $type {
451 fn exp (self) -> Self {
452 self.exp()
453 }
454 }
455 impl Sqrt for $type {
456 fn sqrt (self) -> Self {
457 self.sqrt()
458 }
459 }
460 impl Trig for $type {
461 fn sin (self) -> Self {
462 self.sin()
463 }
464 fn sin_cos (self) -> (Self, Self) {
465 self.sin_cos()
466 }
467 fn cos (self) -> Self {
468 self.cos()
469 }
470 fn tan (self) -> Self {
471 self.tan()
472 }
473 fn asin (self) -> Self {
474 self.asin()
475 }
476 fn acos (self) -> Self {
477 self.acos()
478 }
479 fn atan (self) -> Self {
480 self.atan()
481 }
482 fn atan2 (self, other : Self) -> Self {
483 self.atan2 (other)
484 }
485 }
486}
487
488impl_real_float!(f32);
489impl_real_float!(f64);