#pragma once #include "vde/core/point.h" #include "vde/core/aabb.h" #include #include namespace vde::core { class Polygon2D { public: Polygon2D() = default; explicit Polygon2D(std::vector vertices) : vertices_(std::move(vertices)) {} [[nodiscard]] const std::vector& vertices() const { return vertices_; } [[nodiscard]] size_t size() const { return vertices_.size(); } [[nodiscard]] bool empty() const { return vertices_.empty(); } /// Signed area (positive = CCW) [[nodiscard]] double signed_area() const; /// Absolute area [[nodiscard]] double area() const { return std::abs(signed_area()); } /// Perimeter (sum of edge lengths) [[nodiscard]] double perimeter() const; /// Area-weighted centroid [[nodiscard]] Point2D centroid() const; /// Axis-aligned bounding box (2D, stored in AABB3D with z=0) [[nodiscard]] AABB bounding_box() const; /// Point-in-polygon test (ray casting) [[nodiscard]] bool contains(const Point2D& p) const; /// Is the polygon counter-clockwise? [[nodiscard]] bool is_ccw() const { return signed_area() > 0; } /// Douglas-Peucker simplification. Returns a new simplified polygon. [[nodiscard]] Polygon2D simplify(double tolerance) const; /// Ear-clipping triangulation. Returns triangles as triples of vertex indices. /// Assumes a simple polygon (no self-intersections). CCW ordering required. [[nodiscard]] std::vector> triangulate() const; /// Andrew's monotone chain convex hull of a point set. static Polygon2D convex_hull_2d(const std::vector& points); private: std::vector vertices_; }; } // namespace vde::core