1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use approx::abs_diff_eq;
use num::{Signed, Zero};
use std::cmp::Ordering;
use theon::query::{Line, Plane};
use theon::space::{EuclideanSpace, FiniteDimensional};
use typenum::{U1, U2, U3};
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub enum BinaryPartition {
Left,
Right,
}
pub trait PointPartition<S>
where
S: EuclideanSpace,
{
fn partition(&self, point: S) -> Option<BinaryPartition>;
}
impl<S> PointPartition<S> for S
where
S: EuclideanSpace + FiniteDimensional<N = U1>,
{
fn partition(&self, point: S) -> Option<BinaryPartition> {
let ax = self.into_x();
let px = point.into_x();
match px.partial_cmp(&ax) {
Some(Ordering::Less) => Some(BinaryPartition::Left),
Some(Ordering::Greater) => Some(BinaryPartition::Right),
_ => None,
}
}
}
impl<S> PointPartition<S> for Line<S>
where
S: EuclideanSpace + FiniteDimensional<N = U2>,
{
fn partition(&self, point: S) -> Option<BinaryPartition> {
let (ax, ay) = self.origin.into_xy();
let (bx, by) = (self.origin + *self.direction.get()).into_xy();
let (px, py) = point.into_xy();
let determinant = ((bx - ax) * (py - ay)) - ((by - ay) * (px - ax));
if abs_diff_eq!(determinant, Zero::zero()) {
None
}
else {
Some(if determinant.is_positive() {
BinaryPartition::Left
}
else {
BinaryPartition::Right
})
}
}
}
impl<S> PointPartition<S> for Plane<S>
where
S: EuclideanSpace + FiniteDimensional<N = U3>,
{
fn partition(&self, point: S) -> Option<BinaryPartition> {
let _ = point;
todo!()
}
}