src/sets.rs

branch
dev
changeset 63
f7b87d84864d
parent 41
121cf065e9ed
child 75
e9f4550cfa18
--- a/src/sets.rs	Sat Dec 21 23:32:20 2024 -0500
+++ b/src/sets.rs	Sun Dec 22 14:54:46 2024 -0500
@@ -3,19 +3,19 @@
 */
 
 use std::ops::{RangeFull,RangeFrom,Range,RangeInclusive,RangeTo,RangeToInclusive};
-use std::marker::PhantomData;
 use crate::types::*;
 use crate::loc::Loc;
-use crate::euclidean::Dot;
+use crate::euclidean::Euclidean;
+use crate::instance::{Space, Instance};
 use serde::Serialize;
 
 pub mod cube;
 pub use cube::Cube;
 
 /// Trait for arbitrary sets. The parameter `U` is the element type.
-pub trait Set<U> where U : ?Sized {
+pub trait Set<U> where U : Space {
     /// Check for element containment
-    fn contains(&self, item : &U) -> bool;
+    fn contains<I : Instance<U>>(&self, item : I) -> bool;
 }
 
 /// Additional ordering (besides [`PartialOrd`]) of a subfamily of sets:
@@ -31,22 +31,27 @@
 impl<U, const N : usize> Set<Loc<U, N>>
 for Cube<U,N>
 where U : Num + PartialOrd + Sized {
-    fn contains(&self, item : &Loc<U, N>) -> bool {
-        self.0.iter().zip(item.iter()).all(|(s, x)| s.contains(x))
+    fn contains<I : Instance<Loc<U, N>>>(&self, item : I) -> bool {
+        self.0.iter().zip(item.ref_instance().iter()).all(|(s, x)| s.contains(x))
     }
 }
 
-impl<U> Set<U> for RangeFull {
-    fn contains(&self, _item : &U) -> bool { true }
+impl<U : Space> Set<U> for RangeFull {
+    fn contains<I : Instance<U>>(&self, _item : I) -> bool { true }
 }
 
 macro_rules! impl_ranges {
     ($($range:ident),*) => { $(
-        impl<U,Idx> Set<U>
-        for $range<Idx>
-        where Idx : PartialOrd<U>, U : PartialOrd<Idx> + ?Sized, Idx : PartialOrd {
+        impl<U,Idx> Set<U> for $range<Idx>
+        where
+            Idx : PartialOrd<U>,
+            U : PartialOrd<Idx> + Space,
+            Idx : PartialOrd
+        {
             #[inline]
-            fn contains(&self, item : &U) -> bool { $range::contains(&self, item) }
+            fn contains<I : Instance<U>>(&self, item : I) -> bool {
+                item.eval(|x| $range::contains(&self, x))
+            }
         }
     )* }
 }
@@ -61,40 +66,39 @@
 /// `U` is the element type, `F` the floating point number type, and `A` the type of the
 /// orthogonal (dual) vectors. They need implement [`Dot<U, F>`].
 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)]
-pub struct Halfspace<A, F, U> where A : Dot<U, F>, F : Float {
+pub struct Halfspace<A, F> where A : Euclidean<F>, F : Float {
     pub orthogonal : A,
     pub offset : F,
-    _phantom : PhantomData<U>,
 }
 
-impl<A,F,U> Halfspace<A,F,U> where A : Dot<U,F>, F : Float {
+impl<A,F> Halfspace<A,F> where A : Euclidean<F>, F : Float {
     #[inline]
     pub fn new(orthogonal : A, offset : F) -> Self {
-        Halfspace{ orthogonal : orthogonal, offset : offset, _phantom : PhantomData }
+        Halfspace{ orthogonal : orthogonal, offset : offset }
     }
 }
 
 /// Trait for generating a halfspace spanned by another set `Self` of elements of type `U`.
-pub trait SpannedHalfspace<F, U> where  F : Float {
+pub trait SpannedHalfspace<F> where  F : Float {
     /// Type of the orthogonal vector describing the halfspace.
-    type A : Dot<U, F>;
+    type A : Euclidean<F>;
     /// Returns the halfspace spanned by this set.
-    fn spanned_halfspace(&self) -> Halfspace<Self::A, F, U>;
+    fn spanned_halfspace(&self) -> Halfspace<Self::A, F>;
 }
 
 // TODO: Gram-Schmidt for higher N.
-impl<F : Float> SpannedHalfspace<F,Loc<F, 1>> for [Loc<F, 1>; 2] {
+impl<F : Float> SpannedHalfspace<F> for [Loc<F, 1>; 2] {
     type A = Loc<F, 1>;
-    fn spanned_halfspace(&self) -> Halfspace<Self::A, F, Loc<F, 1>> {
+    fn spanned_halfspace(&self) -> Halfspace<Self::A, F> {
         let (x0, x1) = (self[0], self[1]);
         Halfspace::new(x1-x0, x0[0])
     }
 }
 
 // TODO: Gram-Schmidt for higher N.
-impl<F : Float> SpannedHalfspace<F,Loc<F, 2>> for [Loc<F, 2>; 2] {
+impl<F : Float> SpannedHalfspace<F> for [Loc<F, 2>; 2] {
     type A = Loc<F, 2>;
-    fn spanned_halfspace(&self) -> Halfspace<Self::A, F, Loc<F, 2>> {
+    fn spanned_halfspace(&self) -> Halfspace<Self::A, F> {
         let (x0, x1) = (&self[0], &self[1]);
         let d = x1 - x0;
         let orthog = loc![d[1], -d[0]]; // We don't normalise for efficiency
@@ -103,19 +107,29 @@
     }
 }
 
-impl<A,U,F> Set<U> for Halfspace<A,F,U> where A : Dot<U,F>, F : Float {
+impl<A,F> Set<A> for Halfspace<A,F>
+where
+    A : Euclidean<F>,
+    F : Float,
+{
     #[inline]
-    fn contains(&self, item : &U) -> bool {
+    fn contains<I : Instance<A>>(&self, item : I) -> bool {
         self.orthogonal.dot(item) >= self.offset
     }
 }
 
 /// Polygons defined by `N` `Halfspace`s.
 #[derive(Clone,Copy,Debug,Eq,PartialEq)]
-pub struct NPolygon<A, F, U, const N : usize>(pub [Halfspace<A,F,U>; N]) where A : Dot<U,F>, F : Float;
+pub struct NPolygon<A, F, const N : usize>(pub [Halfspace<A,F>; N])
+where A : Euclidean<F>, F : Float;
 
-impl<A,U,F,const N : usize> Set<U> for NPolygon<A,F,U,N> where A : Dot<U,F>, F : Float {
-    fn contains(&self, item : &U) -> bool {
-        self.0.iter().all(|halfspace| halfspace.contains(item))
+impl<A,F,const N : usize> Set<A> for NPolygon<A,F,N>
+where
+    A : Euclidean<F>,
+    F : Float,
+{
+    fn contains<I : Instance<A>>(&self, item : I) -> bool {
+        let r = item.ref_instance();
+        self.0.iter().all(|halfspace| halfspace.contains(r))
     }
 }

mercurial