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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Relation {
/// geometry is a strict subset of the other
/// and interior/boundary of the geometry is a subset
/// of interior/boundary of the other
Component,
/// geometry is a strict superset of the other
/// and interior/boundary of the geometry is a superset
/// of interior/boundary of the other
Composite,
/// interior of the geometry is a superset of the other
Cover,
/// intersection is a strict subset of each of the geometries,
/// has dimension less than at least of one of the geometries,
/// one of the geometries intersects interior of the other
/// or if we traverse boundary of each of the geometries in any direction
/// then boundary of the other geometry will be on both sides
/// at some point of boundaries intersection
Cross,
/// at least one geometry is non-empty and intersection is empty
Disjoint,
/// at least one boundary point of the geometry
/// lies on the boundary of the other, but not all,
/// other points of the geometry lie in the interior of the other
Enclosed,
/// boundary of the geometry contains
/// at least one boundary point of the other, but not all,
/// interior of the geometry contains other points of the other
Encloses,
/// geometries are equal
Equal,
/// intersection is a strict subset of each of the geometries
/// and has the same dimension as geometries
Overlap,
/// intersection is a strict subset of each of the geometries,
/// has dimension less than at least of one of the geometries
/// and only boundaries intersect, but do not cross
Touch,
/// geometry is a subset of the interior of the other
Within,
}
impl Relation {
pub fn to_complement(self) -> Relation {
match self {
Relation::Composite => Relation::Component,
Relation::Component => Relation::Composite,
Relation::Cover => Relation::Within,
Relation::Enclosed => Relation::Encloses,
Relation::Encloses => Relation::Enclosed,
Relation::Within => Relation::Cover,
relation => relation,
}
}
}
pub trait Relatable<Other = Self> {
fn component_of(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Component
}
fn composite_with(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Composite
}
fn covers(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Cover
}
fn crosses(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Cross
}
fn disjoint_with(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Disjoint
}
fn enclosed_by(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Enclosed
}
fn encloses(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Encloses
}
fn equals_to(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Equal
}
fn overlaps(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Overlap
}
fn touches(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Touch
}
fn within(self, other: Other) -> bool
where
Self: Sized,
{
self.relate_to(other) == Relation::Within
}
fn relate_to(self, other: Other) -> Relation;
}