Skip to main content

geometry_algorithm/
dyn_within.rs

1//! `within_dyn` — runtime-dispatched point-in-polygon for
2//! [`DynGeometry`].
3//!
4//! Supported pair: `(Point, Polygon)`. Anything else returns
5//! `Err(DynKindMismatch)`. Mirrors `algorithms/within.hpp`'s static
6//! per-tag dispatch reached through the variant. `MultiPolygon` is not
7//! yet a `WithinStrategy` target in v1, so `(Point, MultiPolygon)` is
8//! unsupported for now.
9
10use geometry_coords::CoordinateScalar;
11use geometry_cs::{CartesianFamily, CoordinateSystem};
12use geometry_model::{DynGeometry, DynKind, Point, Polygon};
13use geometry_strategy::{WithinStrategy, WithinStrategyForKind};
14use geometry_tag::{PolygonTag, SameAs};
15
16use crate::dyn_error::DynKindMismatch;
17use crate::within::within;
18
19const SUPPORTED: &[&[DynKind]] = &[&[DynKind::Point, DynKind::Polygon]];
20
21/// Runtime-dispatched point-in-polygon.
22///
23/// Returns `Ok(true/false)` for `(Point, Polygon)`.
24///
25/// # Errors
26///
27/// Returns `Err(DynKindMismatch)` for every other kind combination.
28pub fn within_dyn<S, Cs>(
29    a: &DynGeometry<S, Cs>,
30    b: &DynGeometry<S, Cs>,
31) -> Result<bool, DynKindMismatch>
32where
33    S: CoordinateScalar,
34    Cs: CoordinateSystem,
35    Cs::Family: SameAs<CartesianFamily>,
36    <PolygonTag as WithinStrategyForKind>::S:
37        WithinStrategy<Point<S, 2, Cs>, Polygon<Point<S, 2, Cs>>>,
38{
39    use DynGeometry::{Point as PointArm, Polygon as PolygonArm};
40    match (a, b) {
41        (PointArm(p), PolygonArm(pg)) => Ok(within(p, pg)),
42        _ => Err(DynKindMismatch {
43            got: alloc::vec![a.kind(), b.kind()],
44            expected: SUPPORTED,
45        }),
46    }
47}