1use geometry_strategy::{WithinStrategy, WithinStrategyForKind};
16use geometry_trait::{Geometry, Point};
17
18#[inline]
33#[must_use]
34pub fn within<P, G>(p: &P, g: &G) -> bool
35where
36 P: Point,
37 G: Geometry,
38 G::Kind: WithinStrategyForKind,
39 <G::Kind as WithinStrategyForKind>::S: WithinStrategy<P, G>,
40{
41 <<G::Kind as WithinStrategyForKind>::S as Default>::default().within(p, g)
42}
43
44#[inline]
53#[must_use]
54pub fn covered_by<P, G>(p: &P, g: &G) -> bool
55where
56 P: Point,
57 G: Geometry,
58 G::Kind: WithinStrategyForKind,
59 <G::Kind as WithinStrategyForKind>::S: WithinStrategy<P, G>,
60{
61 <<G::Kind as WithinStrategyForKind>::S as Default>::default().covered_by(p, g)
62}
63
64#[cfg(test)]
65mod tests {
66 use super::{covered_by, within};
71 use geometry_cs::Cartesian;
72 use geometry_model::{Box, Point2D, Polygon, Ring, polygon};
73
74 type P = Point2D<f64, Cartesian>;
75
76 fn pt(x: f64, y: f64) -> P {
77 Point2D::new(x, y)
78 }
79
80 fn box_polygon() -> Polygon<P> {
81 polygon![[(0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0), (0.0, 0.0)]]
82 }
83
84 #[test]
86 fn box_b1_inside() {
87 assert!(within(&pt(1.0, 1.0), &box_polygon()));
88 }
89
90 #[test]
92 fn box_b2_outside() {
93 assert!(!within(&pt(3.0, 3.0), &box_polygon()));
94 }
95
96 #[test]
98 fn box_corners_excluded() {
99 let p = box_polygon();
100 for (x, y) in [(0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0)] {
101 assert!(!within(&pt(x, y), &p), "corner ({x},{y})");
102 }
103 }
104
105 #[test]
107 fn box_sides_excluded() {
108 let p = box_polygon();
109 for (x, y) in [(0.0, 1.0), (1.0, 2.0), (2.0, 1.0), (1.0, 0.0)] {
110 assert!(!within(&pt(x, y), &p), "side ({x},{y})");
111 }
112 }
113
114 fn triangle() -> Polygon<P> {
115 polygon![[(0.0, 0.0), (0.0, 4.0), (6.0, 0.0), (0.0, 0.0)]]
116 }
117
118 #[test]
120 fn triangle_t1_inside() {
121 assert!(within(&pt(1.0, 1.0), &triangle()));
122 }
123
124 #[test]
126 fn triangle_t2_outside() {
127 assert!(!within(&pt(3.0, 3.0), &triangle()));
128 }
129
130 fn with_hole() -> Polygon<P> {
131 polygon![
132 [(0.0, 0.0), (0.0, 3.0), (3.0, 3.0), (3.0, 0.0), (0.0, 0.0)],
133 [(1.0, 1.0), (2.0, 1.0), (2.0, 2.0), (1.0, 2.0), (1.0, 1.0)]
134 ]
135 }
136
137 #[test]
139 fn hole_h1_in_outer_not_hole() {
140 assert!(within(&pt(0.5, 0.5), &with_hole()));
141 }
142
143 #[test]
145 fn hole_h2a_in_hole_not_within() {
146 assert!(!within(&pt(1.5, 1.5), &with_hole()));
147 }
148
149 #[test]
152 fn covered_by_includes_boundary() {
153 let p = box_polygon();
154 assert!(covered_by(&pt(0.0, 0.0), &p)); assert!(covered_by(&pt(0.0, 1.0), &p)); assert!(covered_by(&pt(1.0, 1.0), &p)); assert!(!covered_by(&pt(3.0, 3.0), &p)); }
159
160 #[test]
164 fn quickstart_polygon_3_7_2_0_is_within() {
165 let q: Polygon<P> = polygon![[
166 (2.0, 1.3),
167 (2.4, 1.7),
168 (2.8, 1.8),
169 (3.4, 1.2),
170 (3.7, 1.6),
171 (3.4, 2.0),
172 (4.1, 3.0),
173 (5.3, 2.6),
174 (5.4, 1.2),
175 (4.9, 0.8),
176 (2.9, 0.7),
177 (2.0, 1.3)
178 ]];
179 assert!(within(&pt(3.7, 2.0), &q));
180 }
181
182 #[test]
185 fn box_geometry_within_and_covered_by() {
186 let b = Box::from_corners(pt(0.0, 0.0), pt(2.0, 2.0));
187 assert!(within(&pt(1.0, 1.0), &b));
188 assert!(!within(&pt(0.0, 0.0), &b));
189 assert!(covered_by(&pt(0.0, 0.0), &b));
190 assert!(!covered_by(&pt(3.0, 3.0), &b));
191 }
192
193 #[test]
195 fn ring_within_and_covered_by() {
196 let r: Ring<P> = Ring::from_vec(vec![
197 pt(0.0, 0.0),
198 pt(0.0, 2.0),
199 pt(2.0, 2.0),
200 pt(2.0, 0.0),
201 pt(0.0, 0.0),
202 ]);
203 assert!(within(&pt(1.0, 1.0), &r));
204 assert!(!within(&pt(0.0, 0.0), &r));
205 assert!(covered_by(&pt(0.0, 0.0), &r));
206 }
207}