// polygon_winding.h #pragma once #include #include #include #include // Type aliases for convenience using Point2d = Eigen::Vector2d; using PolygonRing = std::vector; /** * @brief Determines if a point is inside a polygon with holes using the non-zero winding rule. * * @param P The query point. * @param outer_ring The outer boundary of the polygon (should be counter-clockwise). * @param holes A list of inner rings (holes), each should be clockwise. * @return true if the point is inside (including boundary), false otherwise. */ bool point_in_polygon_with_holes( const Point2d& P, const PolygonRing& outer_ring, const std::vector& holes ); /** * @brief Computes the winding number of a point with respect to a single closed ring. * * @param P The query point. * @param ring A closed polygonal ring (at least 3 vertices). * @return The winding number (positive for counter-clockwise turns). */ int compute_winding_number_ring(const Point2d& P, const PolygonRing& ring); /** * @brief Validates the polygon input for correct orientation and sufficient vertices. * * @param query_point The query point (for logging purposes). * @param outer_ring The outer boundary ring. * @param holes The list of hole rings. * @param context Optional context string for logging. * @return true if valid, false otherwise. */ bool validate_polygon_input( const Point2d& query_point, const PolygonRing& outer_ring, const std::vector& holes, const std::string& context = "" ); /** * @brief Computes the signed area of a polygon ring. * * @param ring The polygon ring (closed). * @return The signed area (positive if CCW, negative if CW). */ double compute_ring_area(const PolygonRing& ring);