#include "MinAreaBoundingBox.hpp" #include #include #include #if !defined(HAS_INTRINSIC_128_TYPE) || defined(__APPLE__) #include #endif #include #include namespace libnest2d { template<> struct PointType { using Type = Slic3r::Point; }; template<> struct CoordType { using Type = coord_t; }; template<> struct ShapeTag { using Type = PolygonTag; }; template<> struct ShapeTag { using Type = PolygonTag; }; template<> struct ShapeTag { using Type = PathTag; }; template<> struct ShapeTag { using Type = PointTag; }; template<> struct ContourType { using Type = Slic3r::Points; }; template<> struct ContourType { using Type = Slic3r::Points; }; namespace pointlike { template<> inline coord_t x(const Slic3r::Point& p) { return p.x(); } template<> inline coord_t y(const Slic3r::Point& p) { return p.y(); } template<> inline coord_t& x(Slic3r::Point& p) { return p.x(); } template<> inline coord_t& y(Slic3r::Point& p) { return p.y(); } } // pointlike namespace shapelike { template<> inline Slic3r::Points& contour(Slic3r::ExPolygon& sh) { return sh.contour.points; } template<> inline const Slic3r::Points& contour(const Slic3r::ExPolygon& sh) { return sh.contour.points; } template<> inline Slic3r::Points& contour(Slic3r::Polygon& sh) { return sh.points; } template<> inline const Slic3r::Points& contour(const Slic3r::Polygon& sh) { return sh.points; } template<> Slic3r::Points::iterator begin(Slic3r::Points& pts, const PathTag&) { return pts.begin();} template<> Slic3r::Points::const_iterator cbegin(const Slic3r::Points& pts, const PathTag&) { return pts.cbegin(); } template<> Slic3r::Points::iterator end(Slic3r::Points& pts, const PathTag&) { return pts.end();} template<> Slic3r::Points::const_iterator cend(const Slic3r::Points& pts, const PathTag&) { return pts.cend(); } template<> inline Slic3r::ExPolygon create(Slic3r::Points&& contour) { Slic3r::ExPolygon expoly; expoly.contour.points.swap(contour); return expoly; } template<> inline Slic3r::Polygon create(Slic3r::Points&& contour) { Slic3r::Polygon poly; poly.points.swap(contour); return poly; } } // shapelike } // libnest2d namespace Slic3r { // Used as compute type. using Unit = int64_t; #if !defined(HAS_INTRINSIC_128_TYPE) || defined(__APPLE__) using Rational = boost::rational; #else using Rational = boost::rational<__int128>; #endif MinAreaBoundigBox::MinAreaBoundigBox(const Polygon &p, PolygonLevel pc) { const Polygon &chull = pc == pcConvex ? p : libnest2d::sl::convexHull(p); libnest2d::RotatedBox box = libnest2d::minAreaBoundingBox(chull); m_right = libnest2d::cast(box.right_extent()); m_bottom = libnest2d::cast(box.bottom_extent()); m_axis = box.axis(); } MinAreaBoundigBox::MinAreaBoundigBox(const ExPolygon &p, PolygonLevel pc) { const ExPolygon &chull = pc == pcConvex ? p : libnest2d::sl::convexHull(p); libnest2d::RotatedBox box = libnest2d::minAreaBoundingBox(chull); m_right = libnest2d::cast(box.right_extent()); m_bottom = libnest2d::cast(box.bottom_extent()); m_axis = box.axis(); } MinAreaBoundigBox::MinAreaBoundigBox(const Points &pts, PolygonLevel pc) { const Points &chull = pc == pcConvex ? pts : libnest2d::sl::convexHull(pts); libnest2d::RotatedBox box = libnest2d::minAreaBoundingBox(chull); m_right = libnest2d::cast(box.right_extent()); m_bottom = libnest2d::cast(box.bottom_extent()); m_axis = box.axis(); } double MinAreaBoundigBox::angle_to_X() const { double ret = std::atan2(m_axis.y(), m_axis.x()); auto s = std::signbit(ret); if (s) ret += 2 * PI; return -ret; } long double MinAreaBoundigBox::width() const { return std::abs(m_bottom) / std::sqrt(libnest2d::pl::magnsq(m_axis)); } long double MinAreaBoundigBox::height() const { return std::abs(m_right) / std::sqrt(libnest2d::pl::magnsq(m_axis)); } long double MinAreaBoundigBox::area() const { long double asq = libnest2d::pl::magnsq(m_axis); return m_bottom * m_right / asq; } void remove_collinear_points(Polygon &p) { p = libnest2d::removeCollinearPoints(p, Unit(0)); } void remove_collinear_points(ExPolygon &p) { p = libnest2d::removeCollinearPoints(p, Unit(0)); } } // namespace Slic3r