bool Polygon::DiagonalExists(int i, int j) const { assume(p.size() >= 3); assume(i >= 0); assume(j >= 0); assume(i < (int)p.size()); assume(j < (int)p.size()); #ifndef MATH_ENABLE_INSECURE_OPTIMIZATIONS if (p.size() < 3 || i < 0 || j < 0 || i >= (int)p.size() || j >= (int)p.size()) return false; #endif assume(IsPlanar()); assume(i != j); if (i == j) // Degenerate if i == j. return false; if (i > j) Swap(i, j); assume(i+1 != j); if (i+1 == j) // Is this LineSegment an edge of this polygon? return false; Plane polygonPlane = PlaneCCW(); LineSegment diagonal = polygonPlane.Project(LineSegment(p[i], p[j])); // First check that this diagonal line is not intersected by an edge of this polygon. for(int k = 0; k < (int)p.size(); ++k) if (!(k == i || k+1 == i || k == j)) if (polygonPlane.Project(LineSegment(p[k], p[k+1])).Intersects(diagonal)) return false; return IsConvex(); }
bool Polygon::IsSimple() const { assume(IsPlanar()); Plane plane = PlaneCCW(); for(int i = 0; i < (int)p.size(); ++i) { LineSegment si = plane.Project(Edge(i)); for(int j = i+2; j < (int)p.size(); ++j) { if (i == 0 && j == (int)p.size() - 1) continue; // These two edges are consecutive and share a vertex. Don't check that pair. LineSegment sj = plane.Project(Edge(j)); if (si.Intersects(sj)) return false; } } return true; }
bool Polygon::Contains(const LineSegment &worldSpaceLineSegment, float polygonThickness) const { if (p.size() < 3) return false; Plane plane = PlaneCCW(); if (plane.Distance(worldSpaceLineSegment.a) > polygonThickness || plane.Distance(worldSpaceLineSegment.b) > polygonThickness) return false; // For robustness, project onto the polygon plane. LineSegment l = plane.Project(worldSpaceLineSegment); if (!Contains(l.a) || !Contains(l.b)) return false; for(int i = 0; i < (int)p.size(); ++i) if (plane.Project(Edge(i)).Intersects(l)) return false; return true; }