29 } |
29 } |
30 |
30 |
31 impl<U, const N : usize> Set<Loc<U, N>> |
31 impl<U, const N : usize> Set<Loc<U, N>> |
32 for Cube<U,N> |
32 for Cube<U,N> |
33 where U : Num + PartialOrd + Sized { |
33 where U : Num + PartialOrd + Sized { |
34 fn contains(&self, item : &Loc<U, N>) -> bool { |
34 fn contains<I : Instance<Loc<U, N>>>(&self, item : I) -> bool { |
35 self.0.iter().zip(item.iter()).all(|(s, x)| s.contains(x)) |
35 self.0.iter().zip(item.ref_instance().iter()).all(|(s, x)| s.contains(x)) |
36 } |
36 } |
37 } |
37 } |
38 |
38 |
39 impl<U> Set<U> for RangeFull { |
39 impl<U : Space> Set<U> for RangeFull { |
40 fn contains(&self, _item : &U) -> bool { true } |
40 fn contains<I : Instance<U>>(&self, _item : I) -> bool { true } |
41 } |
41 } |
42 |
42 |
43 macro_rules! impl_ranges { |
43 macro_rules! impl_ranges { |
44 ($($range:ident),*) => { $( |
44 ($($range:ident),*) => { $( |
45 impl<U,Idx> Set<U> |
45 impl<U,Idx> Set<U> for $range<Idx> |
46 for $range<Idx> |
46 where |
47 where Idx : PartialOrd<U>, U : PartialOrd<Idx> + ?Sized, Idx : PartialOrd { |
47 Idx : PartialOrd<U>, |
|
48 U : PartialOrd<Idx> + Space, |
|
49 Idx : PartialOrd |
|
50 { |
48 #[inline] |
51 #[inline] |
49 fn contains(&self, item : &U) -> bool { $range::contains(&self, item) } |
52 fn contains<I : Instance<U>>(&self, item : I) -> bool { |
|
53 item.eval(|x| $range::contains(&self, x)) |
|
54 } |
50 } |
55 } |
51 )* } |
56 )* } |
52 } |
57 } |
53 |
58 |
54 impl_ranges!(RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive); |
59 impl_ranges!(RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive); |
55 |
60 |
56 /// Halfspaces described by an orthogonal vector and an offset. |
61 /// Halfspaces described by an orthogonal vector and an offset. |
57 /// |
62 /// |
58 /// The halfspace is $H = \\{ t v + a \mid a^⊤ v = 0 \\}$, where $v$ is the orthogonal |
63 /// The halfspace is $H = \\{ t v + a \mid a^⊤ v = 0 \\}$, where $v$ is the orthogonal |
59 /// vector and $t$ the offset. |
64 /// vector and $t$ the offset. |
60 /// |
|
61 /// `U` is the element type, `F` the floating point number type, and `A` the type of the |
|
62 /// orthogonal (dual) vectors. They need implement [`Dot<U, F>`]. |
|
63 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
65 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
64 pub struct Halfspace<A, F, U> where A : Dot<U, F>, F : Float { |
66 pub struct Halfspace<A, F> where A : Euclidean<F>, F : Float { |
65 pub orthogonal : A, |
67 pub orthogonal : A, |
66 pub offset : F, |
68 pub offset : F, |
67 _phantom : PhantomData<U>, |
|
68 } |
69 } |
69 |
70 |
70 impl<A,F,U> Halfspace<A,F,U> where A : Dot<U,F>, F : Float { |
71 impl<A,F> Halfspace<A,F> where A : Euclidean<F>, F : Float { |
71 #[inline] |
72 #[inline] |
72 pub fn new(orthogonal : A, offset : F) -> Self { |
73 pub fn new(orthogonal : A, offset : F) -> Self { |
73 Halfspace{ orthogonal : orthogonal, offset : offset, _phantom : PhantomData } |
74 Halfspace{ orthogonal : orthogonal, offset : offset } |
74 } |
75 } |
75 } |
76 } |
76 |
77 |
77 /// Trait for generating a halfspace spanned by another set `Self` of elements of type `U`. |
78 /// Trait for generating a halfspace spanned by another set `Self` of elements of type `U`. |
78 pub trait SpannedHalfspace<F, U> where F : Float { |
79 pub trait SpannedHalfspace<F> where F : Float { |
79 /// Type of the orthogonal vector describing the halfspace. |
80 /// Type of the orthogonal vector describing the halfspace. |
80 type A : Dot<U, F>; |
81 type A : Euclidean<F>; |
81 /// Returns the halfspace spanned by this set. |
82 /// Returns the halfspace spanned by this set. |
82 fn spanned_halfspace(&self) -> Halfspace<Self::A, F, U>; |
83 fn spanned_halfspace(&self) -> Halfspace<Self::A, F>; |
83 } |
84 } |
84 |
85 |
85 // TODO: Gram-Schmidt for higher N. |
86 // TODO: Gram-Schmidt for higher N. |
86 impl<F : Float> SpannedHalfspace<F,Loc<F, 1>> for [Loc<F, 1>; 2] { |
87 impl<F : Float> SpannedHalfspace<F> for [Loc<F, 1>; 2] { |
87 type A = Loc<F, 1>; |
88 type A = Loc<F, 1>; |
88 fn spanned_halfspace(&self) -> Halfspace<Self::A, F, Loc<F, 1>> { |
89 fn spanned_halfspace(&self) -> Halfspace<Self::A, F> { |
89 let (x0, x1) = (self[0], self[1]); |
90 let (x0, x1) = (self[0], self[1]); |
90 Halfspace::new(x1-x0, x0[0]) |
91 Halfspace::new(x1-x0, x0[0]) |
91 } |
92 } |
92 } |
93 } |
93 |
94 |
94 // TODO: Gram-Schmidt for higher N. |
95 // TODO: Gram-Schmidt for higher N. |
95 impl<F : Float> SpannedHalfspace<F,Loc<F, 2>> for [Loc<F, 2>; 2] { |
96 impl<F : Float> SpannedHalfspace<F> for [Loc<F, 2>; 2] { |
96 type A = Loc<F, 2>; |
97 type A = Loc<F, 2>; |
97 fn spanned_halfspace(&self) -> Halfspace<Self::A, F, Loc<F, 2>> { |
98 fn spanned_halfspace(&self) -> Halfspace<Self::A, F> { |
98 let (x0, x1) = (&self[0], &self[1]); |
99 let (x0, x1) = (&self[0], &self[1]); |
99 let d = x1 - x0; |
100 let d = x1 - x0; |
100 let orthog = loc![d[1], -d[0]]; // We don't normalise for efficiency |
101 let orthog = loc![d[1], -d[0]]; // We don't normalise for efficiency |
101 let offset = x0.dot(&orthog); |
102 let offset = x0.dot(&orthog); |
102 Halfspace::new(orthog, offset) |
103 Halfspace::new(orthog, offset) |
103 } |
104 } |
104 } |
105 } |
105 |
106 |
106 impl<A,U,F> Set<U> for Halfspace<A,F,U> where A : Dot<U,F>, F : Float { |
107 impl<A,F> Set<A> for Halfspace<A,F> |
|
108 where |
|
109 A : Euclidean<F>, |
|
110 F : Float, |
|
111 { |
107 #[inline] |
112 #[inline] |
108 fn contains(&self, item : &U) -> bool { |
113 fn contains<I : Instance<A>>(&self, item : I) -> bool { |
109 self.orthogonal.dot(item) >= self.offset |
114 self.orthogonal.dot(item) >= self.offset |
110 } |
115 } |
111 } |
116 } |
112 |
117 |
113 /// Polygons defined by `N` `Halfspace`s. |
118 /// Polygons defined by `N` `Halfspace`s. |
114 #[derive(Clone,Copy,Debug,Eq,PartialEq)] |
119 #[derive(Clone,Copy,Debug,Eq,PartialEq)] |
115 pub struct NPolygon<A, F, U, const N : usize>(pub [Halfspace<A,F,U>; N]) where A : Dot<U,F>, F : Float; |
120 pub struct NPolygon<A, F, const N : usize>(pub [Halfspace<A,F>; N]) |
|
121 where A : Euclidean<F>, F : Float; |
116 |
122 |
117 impl<A,U,F,const N : usize> Set<U> for NPolygon<A,F,U,N> where A : Dot<U,F>, F : Float { |
123 impl<A,F,const N : usize> Set<A> for NPolygon<A,F,N> |
118 fn contains(&self, item : &U) -> bool { |
124 where |
119 self.0.iter().all(|halfspace| halfspace.contains(item)) |
125 A : Euclidean<F>, |
|
126 F : Float, |
|
127 { |
|
128 fn contains<I : Instance<A>>(&self, item : I) -> bool { |
|
129 let r = item.ref_instance(); |
|
130 self.0.iter().all(|halfspace| halfspace.contains(r)) |
120 } |
131 } |
121 } |
132 } |