Sat, 22 Oct 2022 18:12:49 +0300
Fix some unit tests after fundamental changes that made them invalid
| 0 | 1 | /// Various types of sets. |
| 2 | use std::ops::{RangeFull,RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive}; | |
| 3 | use std::marker::PhantomData; | |
| 4 | use crate::types::*; | |
| 5 | use crate::loc::{Loc}; | |
| 6 | use crate::norms::Dot; | |
| 7 | use serde::Serialize; | |
| 8 | ||
| 9 | pub mod cube; | |
| 10 | pub use cube::*; | |
| 11 | ||
| 12 | /// Trait for arbitrary sets. The parameter `U` is the element type. | |
| 13 | pub trait Set<U> where U : ?Sized { | |
| 14 | /// Check for containment. | |
| 15 | fn contains(&self, item : &U) -> bool; | |
| 16 | } | |
| 17 | ||
| 18 | pub trait SetOrd : Sized { | |
| 19 | /// Returns the smallest set of same class contain both parameters. | |
| 20 | fn common(&self, other : &Self) -> Self; | |
| 21 | ||
| 22 | /// Returns the greatest set of same class contaied by n both parameter sets. | |
| 23 | fn intersect(&self, other : &Self) -> Option<Self>; | |
| 24 | } | |
| 25 | ||
| 26 | impl<U, const N : usize> Set<Loc<U, N>> | |
| 27 | for Cube<U,N> | |
| 28 | where U : Num + PartialOrd + Sized { | |
| 29 | fn contains(&self, item : &Loc<U, N>) -> bool { | |
| 30 | self.0.iter().zip(item.iter()).all(|(s, x)| s.contains(x)) | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | impl<U> Set<U> for RangeFull { | |
| 35 | fn contains(&self, _item : &U) -> bool { true } | |
| 36 | } | |
| 37 | ||
| 38 | macro_rules! impl_ranges { | |
| 39 | ($($range:ident),*) => { $( | |
| 40 | impl<U,Idx> Set<U> | |
| 41 | for $range<Idx> | |
| 42 | where Idx : PartialOrd<U>, U : PartialOrd<Idx> + ?Sized, Idx : PartialOrd { | |
| 43 | #[inline] | |
| 44 | fn contains(&self, item : &U) -> bool { $range::contains(&self, item) } | |
| 45 | } | |
| 46 | )* } | |
| 47 | } | |
| 48 | ||
| 49 | impl_ranges!(RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive); | |
| 50 | ||
| 51 | /// Halfspace. The orthogonal (dual) vectors `A` are supposed to implement [`Dot`]`<U,F>` | |
| 52 | /// for `U` the element type. | |
| 53 | #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] | |
| 54 | pub struct Halfspace<A, F, U> where A : Dot<U,F>, F : Float { | |
| 55 | pub orthogonal : A, | |
| 56 | pub offset : F, | |
| 57 | _phantom : PhantomData<U>, | |
| 58 | } | |
| 59 | ||
| 60 | impl<A,F,U> Halfspace<A,F,U> where A : Dot<U,F>, F : Float { | |
| 61 | #[inline] | |
| 62 | pub fn new(orthogonal : A, offset : F) -> Self { | |
| 63 | Halfspace{ orthogonal : orthogonal, offset : offset, _phantom : PhantomData } | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | pub trait SpannedHalfspace<F,U> where F : Float { | |
| 68 | type A : Dot<U,F>; | |
| 69 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F, U>; | |
| 70 | } | |
| 71 | ||
| 72 | // TODO: Gram-Schmidt for higher N. | |
| 73 | impl<F : Float> SpannedHalfspace<F,Loc<F, 1>> for [Loc<F, 1>; 2] { | |
| 74 | type A = Loc<F, 1>; | |
| 75 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F, Loc<F, 1>> { | |
| 76 | let (x0, x1) = (self[0], self[1]); | |
| 77 | Halfspace::new(x1-x0, x0[0]) | |
| 78 | } | |
| 79 | } | |
| 80 | ||
| 81 | // TODO: Gram-Schmidt for higher N. | |
| 82 | impl<F : Float> SpannedHalfspace<F,Loc<F, 2>> for [Loc<F, 2>; 2] { | |
| 83 | type A = Loc<F, 2>; | |
| 84 | fn spanned_halfspace(&self) -> Halfspace<Self::A, F, Loc<F, 2>> { | |
| 85 | let (x0, x1) = (&self[0], &self[1]); | |
| 86 | let d = x1 - x0; | |
| 87 | let orthog = loc![d[1], -d[0]]; // We don't normalise for efficiency | |
| 88 | let offset = x0.dot(&orthog); | |
| 89 | Halfspace::new(orthog, offset) | |
| 90 | } | |
| 91 | } | |
| 92 | ||
| 93 | impl<A,U,F> Set<U> for Halfspace<A,F,U> where A : Dot<U,F>, F : Float { | |
| 94 | #[inline] | |
| 95 | fn contains(&self, item : &U) -> bool { | |
| 96 | self.orthogonal.dot(item) >= self.offset | |
| 97 | } | |
| 98 | } | |
| 99 | ||
| 100 | /// Polygons defined by `N` `Halfspace`s. | |
| 101 | #[derive(Clone,Copy,Debug,Eq,PartialEq)] | |
| 102 | pub struct NPolygon<A, F, U, const N : usize>(pub [Halfspace<A,F,U>; N]) where A : Dot<U,F>, F : Float; | |
| 103 | ||
| 104 | impl<A,U,F,const N : usize> Set<U> for NPolygon<A,F,U,N> where A : Dot<U,F>, F : Float { | |
| 105 | fn contains(&self, item : &U) -> bool { | |
| 106 | self.0.iter().all(|halfspace| halfspace.contains(item)) | |
| 107 | } | |
| 108 | } |