aboutsummaryrefslogtreecommitdiff
path: root/src/math/polygon.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/polygon.rs')
-rw-r--r--src/math/polygon.rs169
1 files changed, 0 insertions, 169 deletions
diff --git a/src/math/polygon.rs b/src/math/polygon.rs
deleted file mode 100644
index 5711049..0000000
--- a/src/math/polygon.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-use super::{PolygonGraph, Vec2};
-use nalgebra::{ClosedDiv, ClosedMul, ClosedSub, RealField, Scalar};
-use num_traits::Zero;
-use std::ops::Neg;
-
-#[derive(Debug)]
-// TODO: Support polygons with holes
-pub struct Polygon<T: Scalar + Copy> {
- pub corners: Vec<Vec2<T>>,
-}
-
-impl<T: Scalar + Copy> Polygon<T> {
- pub fn new(corners: Vec<Vec2<T>>) -> Self {
- Self { corners }
- }
-
- /// Check whether a point is inside a polygon or not. If a point lies on an edge, it also
- /// counts as inside the polygon.
- pub fn contains_point(&self, p: Vec2<T>) -> bool
- where
- T: Zero + ClosedSub + ClosedMul + ClosedDiv + Neg<Output = T> + PartialOrd,
- {
- let n = self.corners.len();
-
- let a = self.corners[n - 1];
- let mut b = self.corners[n - 2];
- let mut ax;
- let mut ay = a.y - p.y;
- let mut bx = b.x - p.x;
- let mut by = b.y - p.y;
-
- let mut lup = by > ay;
- for i in 0..n {
- // ax = bx;
- ay = by;
- b = self.corners[i];
- bx = b.x - p.x;
- by = b.y - p.y;
-
- if ay == by {
- continue;
- }
- lup = by > ay;
- }
-
- let mut depth = 0;
- for i in 0..n {
- ax = bx;
- ay = by;
- let b = &self.corners[i];
- bx = b.x - p.x;
- by = b.y - p.y;
-
- if ay < T::zero() && by < T::zero() {
- // both "up" or both "down"
- continue;
- }
- if ay > T::zero() && by > T::zero() {
- // both "up" or both "down"
- continue;
- }
- if ax < T::zero() && bx < T::zero() {
- // both points on the left
- continue;
- }
-
- if ay == by && (if ax < bx { ax } else { bx }) <= T::zero() {
- return true;
- }
- if ay == by {
- continue;
- }
-
- let lx = ax + (((bx - ax) * -ay) / (by - ay));
- if lx == T::zero() {
- // point on edge
- return true;
- }
- if lx > T::zero() {
- depth += 1;
- }
- if ay == T::zero() && lup && by > ay {
- // hit vertex, both up
- depth -= 1;
- }
- if ay == T::zero() && !lup && by < ay {
- // hit vertex, both down
- depth -= 1;
- }
-
- lup = by > ay;
- }
-
- (depth & 1) == 1
- }
-
- /// Join this polygon with another, ensuring the area of the two stays the same, but the
- /// overlap is not doubled, but instead joined into one.
- /// Returns the Polygons themselves, if there is no overlap
- pub fn unite(self, other: Polygon<T>) -> Vec<Polygon<T>>
- where
- T: RealField,
- {
- let mut graph = PolygonGraph::from_polygon(&self);
- graph.add_all(&other);
-
- // TODO: Make bounding box support multiple polygons
- vec![graph.bounding_polygon()]
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn polygon_contains() {
- let polygon = Polygon::new(vec![
- Vec2::new(0., 0.),
- Vec2::new(-1., 1.),
- Vec2::new(0., 2.),
- Vec2::new(1., 3.),
- Vec2::new(3., 1.5),
- Vec2::new(2., 0.),
- Vec2::new(1., 1.),
- ]);
-
- assert!(!polygon.contains_point(Vec2::new(1., -2.)));
- assert!(!polygon.contains_point(Vec2::new(-1., 0.5)));
- assert!(polygon.contains_point(Vec2::new(0., 0.5)));
- assert!(polygon.contains_point(Vec2::new(0.5, 1.)));
- assert!(polygon.contains_point(Vec2::new(0.5, 1.5)));
- assert!(!polygon.contains_point(Vec2::new(-2., 1.9)));
- assert!(!polygon.contains_point(Vec2::new(0., 3.)));
- assert!(polygon.contains_point(Vec2::new(1., 3.)));
- }
-
- #[test]
- fn polygon_union() {
- let first = Polygon::new(vec![
- Vec2::new(-2., 1.),
- Vec2::new(-0.5, 2.5),
- Vec2::new(2., 2.),
- Vec2::new(0.5, 1.5),
- Vec2::new(1., 0.),
- Vec2::new(-0.5, 1.),
- ]);
-
- let second = Polygon::new(vec![
- Vec2::new(0., 0.),
- Vec2::new(-2., 2.),
- Vec2::new(3., 2.),
- Vec2::new(1.5, 0.),
- ]);
-
- let union = first.unite(second);
- assert_eq!(union.len(), 1);
- let union = &union[0];
-
- println!("Union of the two polygons: {:?}", union);
-
- assert_eq!(union.corners.len(), 11);
- assert!(union
- .corners
- .iter()
- .find(|&p| p.x == 0. && p.y == 0.)
- .is_some());
- }
-}