diff --git a/src/libslic3r/Arachne/utils/linearAlg2D.hpp b/src/libslic3r/Arachne/utils/linearAlg2D.hpp index 417e9962dc..797bae0b97 100644 --- a/src/libslic3r/Arachne/utils/linearAlg2D.hpp +++ b/src/libslic3r/Arachne/utils/linearAlg2D.hpp @@ -16,9 +16,8 @@ namespace Slic3r::Arachne::LinearAlg2D * * Test whether the \p query_point is inside of a polygon w.r.t a single corner. */ -inline static bool isInsideCorner(const Point a, const Point b, const Point c, const Vec2i64 query_point) { - - +inline static bool isInsideCorner(const Point &a, const Point &b, const Point &c, const Vec2i64 &query_point) +{ // Visualisation for the algorithm below: // // query @@ -32,47 +31,39 @@ inline static bool isInsideCorner(const Point a, const Point b, const Point c, c // a c // - auto normal = [](const Point& p0, coord_t len) -> Point - { + auto normal = [](const Point &p0, coord_t len) -> Point { int64_t _len = p0.cast().norm(); if (_len < 1) - return Point(len, 0); + return {len, 0}; return (p0.cast() * int64_t(len) / _len).cast(); }; - auto rotate_90_degree_ccw = [](const Vec2i64 &p) -> Vec2i64 { - return Vec2i64(-p.y(), p.x()); + auto rotate_90_degree_ccw = [](const Vec2d &p) -> Vec2d { + return {-p.y(), p.x()}; }; constexpr coord_t normal_length = 10000; //Create a normal vector of reasonable length in order to reduce rounding error. const Point ba = normal(a - b, normal_length); const Point bc = normal(c - b, normal_length); - const Vec2i64 bq = query_point - b.cast(); - const Vec2i64 perpendicular = rotate_90_degree_ccw(bq); //The query projects to this perpendicular to coordinate 0. + const Vec2d bq = query_point.cast() - b.cast(); + const Vec2d perpendicular = rotate_90_degree_ccw(bq); //The query projects to this perpendicular to coordinate 0. - assert(ba.cast().dot(perpendicular.cast()) <= double(std::numeric_limits::max()) && ba.cast().dot(perpendicular.cast()) >= double(std::numeric_limits::lowest())); - assert(bc.cast().dot(perpendicular.cast()) <= double(std::numeric_limits::max()) && bc.cast().dot(perpendicular.cast()) >= double(std::numeric_limits::lowest())); - - const int64_t project_a_perpendicular = ba.cast().dot(perpendicular); //Project vertex A on the perpendicular line. - const int64_t project_c_perpendicular = bc.cast().dot(perpendicular); //Project vertex C on the perpendicular line. - if ((project_a_perpendicular > 0) != (project_c_perpendicular > 0)) //Query is between A and C on the projection. + const double project_a_perpendicular = ba.cast().dot(perpendicular); //Project vertex A on the perpendicular line. + const double project_c_perpendicular = bc.cast().dot(perpendicular); //Project vertex C on the perpendicular line. + if ((project_a_perpendicular > 0.) != (project_c_perpendicular > 0.)) //Query is between A and C on the projection. { - return project_a_perpendicular > 0; //Due to the winding order of corner ABC, this means that the query is inside. + return project_a_perpendicular > 0.; //Due to the winding order of corner ABC, this means that the query is inside. } else //Beyond either A or C, but it could still be inside of the polygon. { - assert(ba.cast().dot(bq.cast()) <= double(std::numeric_limits::max()) && ba.cast().dot(bq.cast()) >= double(std::numeric_limits::lowest())); - assert(bc.cast().dot(bq.cast()) <= double(std::numeric_limits::max()) && bc.cast().dot(bq.cast()) >= double(std::numeric_limits::lowest())); - - const int64_t project_a_parallel = ba.cast().dot(bq); //Project not on the perpendicular, but on the original. - const int64_t project_c_parallel = bc.cast().dot(bq); + const double project_a_parallel = ba.cast().dot(bq); //Project not on the perpendicular, but on the original. + const double project_c_parallel = bc.cast().dot(bq); //Either: // * A is to the right of B (project_a_perpendicular > 0) and C is below A (project_c_parallel < project_a_parallel), or // * A is to the left of B (project_a_perpendicular < 0) and C is above A (project_c_parallel > project_a_parallel). - return (project_c_parallel < project_a_parallel) == (project_a_perpendicular > 0); + return (project_c_parallel < project_a_parallel) == (project_a_perpendicular > 0.); } - } /*! @@ -86,7 +77,7 @@ inline static bool isInsideCorner(const Point a, const Point b, const Point c, c * \param b the to point of the line * \return a positive value when \p p lies to the left of the line from \p a to \p b */ -static inline int64_t pointIsLeftOfLine(const Point& p, const Point& a, const Point& b) +static inline int64_t pointIsLeftOfLine(const Point &p, const Point &a, const Point &b) { return int64_t(b.x() - a.x()) * int64_t(p.y() - a.y()) - int64_t(b.y() - a.y()) * int64_t(p.x() - a.x()); } @@ -108,7 +99,7 @@ static inline int64_t pointIsLeftOfLine(const Point& p, const Point& a, const Po * \param c end of second line segment * \return the angle in radians between 0 and 2 * pi of the corner in \p b */ -static inline float getAngleLeft(const Point& a, const Point& b, const Point& c) +static inline float getAngleLeft(const Point &a, const Point &b, const Point &c) { const Vec2i64 ba = (a - b).cast(); const Vec2i64 bc = (c - b).cast();