diff options
author | tamasmeszaros <meszaros.q@gmail.com> | 2019-07-02 17:08:13 +0300 |
---|---|---|
committer | tamasmeszaros <meszaros.q@gmail.com> | 2019-07-02 17:08:13 +0300 |
commit | 320f2ecefd953cdab7089c0037bc29d0471fed35 (patch) | |
tree | c4c9712a0874b041f0300ee353159e813b584288 /src/libnest2d | |
parent | 87c5e9bbaa264db564bfd8bd6a2f9238791ee2e8 (diff) |
Try to deal with infinite bin.
Diffstat (limited to 'src/libnest2d')
-rw-r--r-- | src/libnest2d/include/libnest2d/geometry_traits.hpp | 532 |
1 files changed, 280 insertions, 252 deletions
diff --git a/src/libnest2d/include/libnest2d/geometry_traits.hpp b/src/libnest2d/include/libnest2d/geometry_traits.hpp index 345252f12..8b87229c0 100644 --- a/src/libnest2d/include/libnest2d/geometry_traits.hpp +++ b/src/libnest2d/include/libnest2d/geometry_traits.hpp @@ -30,11 +30,11 @@ template<class Shape> struct ShapeTag { using Type = typename Shape::Tag; }; template<class S> using Tag = typename ShapeTag<remove_cvref_t<S>>::Type; /// Meta function to derive the contour type for a polygon which could be itself -template<class RawShape> struct ContourType { using Type = RawShape; }; +template<class S> struct ContourType { using Type = S; }; -/// TContour<RawShape> instead of `typename ContourType<RawShape>::type` -template<class RawShape> -using TContour = typename ContourType<remove_cvref_t<RawShape>>::Type; +/// TContour<S> instead of `typename ContourType<S>::type` +template<class S> +using TContour = typename ContourType<remove_cvref_t<S>>::Type; /// Getting the type of point structure used by a shape. template<class Sh> struct PointType { @@ -83,12 +83,12 @@ template<class I> struct ComputeType<I, true> { template<class T> using TCompute = typename ComputeType<remove_cvref_t<T>>::Type; /// A meta function to derive a container type for holes in a polygon -template<class RawShape> -struct HolesContainer { using Type = std::vector<TContour<RawShape>>; }; +template<class S> +struct HolesContainer { using Type = std::vector<TContour<S>>; }; -/// Shorthand for `typename HolesContainer<RawShape>::Type` -template<class RawShape> -using THolesContainer = typename HolesContainer<remove_cvref_t<RawShape>>::Type; +/// Shorthand for `typename HolesContainer<S>::Type` +template<class S> +using THolesContainer = typename HolesContainer<remove_cvref_t<S>>::Type; /* * TContour, TPoint, TCoord and TCompute should be usable for any type for which @@ -132,7 +132,7 @@ enum class Orientation { COUNTER_CLOCKWISE }; -template<class RawShape> +template<class S> struct OrientationType { // Default Polygon orientation that the library expects @@ -146,45 +146,46 @@ template<class T> inline /*constexpr*/ bool is_clockwise() { /** * \brief A point pair base class for other point pairs (segment, box, ...). - * \tparam RawPoint The actual point type to use. + * \tparam P The actual point type to use. */ -template<class RawPoint> +template<class P> struct PointPair { - RawPoint p1; - RawPoint p2; + P p1; + P p2; }; /** * \brief An abstraction of a box; */ -template<class RawPoint> -class _Box: PointPair<RawPoint> { - using PointPair<RawPoint>::p1; - using PointPair<RawPoint>::p2; +template<class P> +class _Box: PointPair<P> { + using PointPair<P>::p1; + using PointPair<P>::p2; public: using Tag = BoxTag; - using PointType = RawPoint; + using PointType = P; - inline _Box() = default; - inline _Box(const RawPoint& p, const RawPoint& pp): - PointPair<RawPoint>({p, pp}) {} - - inline _Box(TCoord<RawPoint> width, TCoord<RawPoint> height): - _Box(RawPoint{0, 0}, RawPoint{width, height}) {} + inline _Box(const P& p = {TCoord<P>(0), TCoord<P>(0)}); + inline _Box(const P& p, const P& pp): + PointPair<P>({p, pp}) {} + + inline _Box(TCoord<P> width, TCoord<P> height, + const P& p = {TCoord<P>(0), TCoord<P>(0)});/*: + _Box(p, P{width, height}) {}*/ - inline const RawPoint& minCorner() const BP2D_NOEXCEPT { return p1; } - inline const RawPoint& maxCorner() const BP2D_NOEXCEPT { return p2; } + inline const P& minCorner() const BP2D_NOEXCEPT { return p1; } + inline const P& maxCorner() const BP2D_NOEXCEPT { return p2; } - inline RawPoint& minCorner() BP2D_NOEXCEPT { return p1; } - inline RawPoint& maxCorner() BP2D_NOEXCEPT { return p2; } + inline P& minCorner() BP2D_NOEXCEPT { return p1; } + inline P& maxCorner() BP2D_NOEXCEPT { return p2; } - inline TCoord<RawPoint> width() const BP2D_NOEXCEPT; - inline TCoord<RawPoint> height() const BP2D_NOEXCEPT; + inline TCoord<P> width() const BP2D_NOEXCEPT; + inline TCoord<P> height() const BP2D_NOEXCEPT; - inline RawPoint center() const BP2D_NOEXCEPT; + inline P center() const BP2D_NOEXCEPT; - template<class Unit = TCompute<RawPoint>> + template<class Unit = TCompute<P>> inline Unit area() const BP2D_NOEXCEPT { return Unit(width())*height(); } @@ -194,20 +195,20 @@ template<class S> struct PointType<_Box<S>> { using Type = typename _Box<S>::PointType; }; -template<class RawPoint> +template<class P> class _Circle { - RawPoint center_; + P center_; double radius_ = 0; public: using Tag = CircleTag; - using PointType = RawPoint; + using PointType = P; _Circle() = default; - _Circle(const RawPoint& center, double r): center_(center), radius_(r) {} + _Circle(const P& center, double r): center_(center), radius_(r) {} - inline const RawPoint& center() const BP2D_NOEXCEPT { return center_; } - inline void center(const RawPoint& c) { center_ = c; } + inline const P& center() const BP2D_NOEXCEPT { return center_; } + inline void center(const P& c) { center_ = c; } inline double radius() const BP2D_NOEXCEPT { return radius_; } inline void radius(double r) { radius_ = r; } @@ -224,38 +225,38 @@ template<class S> struct PointType<_Circle<S>> { /** * \brief An abstraction of a directed line segment with two points. */ -template<class RawPoint> -class _Segment: PointPair<RawPoint> { - using PointPair<RawPoint>::p1; - using PointPair<RawPoint>::p2; +template<class P> +class _Segment: PointPair<P> { + using PointPair<P>::p1; + using PointPair<P>::p2; mutable Radians angletox_ = std::nan(""); public: - using PointType = RawPoint; + using PointType = P; inline _Segment() = default; - inline _Segment(const RawPoint& p, const RawPoint& pp): - PointPair<RawPoint>({p, pp}) {} + inline _Segment(const P& p, const P& pp): + PointPair<P>({p, pp}) {} /** * @brief Get the first point. * @return Returns the starting point. */ - inline const RawPoint& first() const BP2D_NOEXCEPT { return p1; } + inline const P& first() const BP2D_NOEXCEPT { return p1; } /** * @brief The end point. * @return Returns the end point of the segment. */ - inline const RawPoint& second() const BP2D_NOEXCEPT { return p2; } + inline const P& second() const BP2D_NOEXCEPT { return p2; } - inline void first(const RawPoint& p) BP2D_NOEXCEPT + inline void first(const P& p) BP2D_NOEXCEPT { angletox_ = std::nan(""); p1 = p; } - inline void second(const RawPoint& p) BP2D_NOEXCEPT { + inline void second(const P& p) BP2D_NOEXCEPT { angletox_ = std::nan(""); p2 = p; } @@ -263,7 +264,7 @@ public: inline Radians angleToXaxis() const; /// The length of the segment in the measure of the coordinate system. - template<class Unit = TCompute<RawPoint>> inline Unit sqlength() const; + template<class Unit = TCompute<P>> inline Unit sqlength() const; }; @@ -275,42 +276,42 @@ template<class S> struct PointType<_Segment<S>> { // used in friend declarations. namespace pointlike { -template<class RawPoint> -inline TCoord<RawPoint> x(const RawPoint& p) +template<class P> +inline TCoord<P> x(const P& p) { return p.x(); } -template<class RawPoint> -inline TCoord<RawPoint> y(const RawPoint& p) +template<class P> +inline TCoord<P> y(const P& p) { return p.y(); } -template<class RawPoint> -inline TCoord<RawPoint>& x(RawPoint& p) +template<class P> +inline TCoord<P>& x(P& p) { return p.x(); } -template<class RawPoint> -inline TCoord<RawPoint>& y(RawPoint& p) +template<class P> +inline TCoord<P>& y(P& p) { return p.y(); } -template<class RawPoint, class Unit = TCompute<RawPoint>> -inline Unit squaredDistance(const RawPoint& p1, const RawPoint& p2) +template<class P, class Unit = TCompute<P>> +inline Unit squaredDistance(const P& p1, const P& p2) { auto x1 = Unit(x(p1)), y1 = Unit(y(p1)), x2 = Unit(x(p2)), y2 = Unit(y(p2)); Unit a = (x2 - x1), b = (y2 - y1); return a * a + b * b; } -template<class RawPoint> -inline double distance(const RawPoint& p1, const RawPoint& p2) +template<class P> +inline double distance(const P& p1, const P& p2) { - return std::sqrt(squaredDistance<RawPoint, double>(p1, p2)); + return std::sqrt(squaredDistance<P, double>(p1, p2)); } // create perpendicular vector @@ -339,9 +340,9 @@ inline Unit magnsq(const Pt& p) return Unit(x(p)) * x(p) + Unit(y(p)) * y(p); } -template<class RawPoint, class Unit = TCompute<RawPoint>> +template<class P, class Unit = TCompute<P>> inline std::pair<Unit, bool> horizontalDistance( - const RawPoint& p, const _Segment<RawPoint>& s) + const P& p, const _Segment<P>& s) { namespace pl = pointlike; auto x = Unit(pl::x(p)), y = Unit(pl::y(p)); @@ -364,9 +365,9 @@ inline std::pair<Unit, bool> horizontalDistance( return {ret, true}; } -template<class RawPoint, class Unit = TCompute<RawPoint>> +template<class P, class Unit = TCompute<P>> inline std::pair<Unit, bool> verticalDistance( - const RawPoint& p, const _Segment<RawPoint>& s) + const P& p, const _Segment<P>& s) { namespace pl = pointlike; auto x = Unit(pl::x(p)), y = Unit(pl::y(p)); @@ -390,42 +391,42 @@ inline std::pair<Unit, bool> verticalDistance( } } -template<class RawPoint> -TCoord<RawPoint> _Box<RawPoint>::width() const BP2D_NOEXCEPT +template<class P> +TCoord<P> _Box<P>::width() const BP2D_NOEXCEPT { return pointlike::x(maxCorner()) - pointlike::x(minCorner()); } -template<class RawPoint> -TCoord<RawPoint> _Box<RawPoint>::height() const BP2D_NOEXCEPT +template<class P> +TCoord<P> _Box<P>::height() const BP2D_NOEXCEPT { return pointlike::y(maxCorner()) - pointlike::y(minCorner()); } -template<class RawPoint> -TCoord<RawPoint> getX(const RawPoint& p) { return pointlike::x<RawPoint>(p); } +template<class P> +TCoord<P> getX(const P& p) { return pointlike::x<P>(p); } -template<class RawPoint> -TCoord<RawPoint> getY(const RawPoint& p) { return pointlike::y<RawPoint>(p); } +template<class P> +TCoord<P> getY(const P& p) { return pointlike::y<P>(p); } -template<class RawPoint> -void setX(RawPoint& p, const TCoord<RawPoint>& val) +template<class P> +void setX(P& p, const TCoord<P>& val) { - pointlike::x<RawPoint>(p) = val; + pointlike::x<P>(p) = val; } -template<class RawPoint> -void setY(RawPoint& p, const TCoord<RawPoint>& val) +template<class P> +void setY(P& p, const TCoord<P>& val) { - pointlike::y<RawPoint>(p) = val; + pointlike::y<P>(p) = val; } -template<class RawPoint> -inline Radians _Segment<RawPoint>::angleToXaxis() const +template<class P> +inline Radians _Segment<P>::angleToXaxis() const { if(std::isnan(static_cast<double>(angletox_))) { - TCoord<RawPoint> dx = getX(second()) - getX(first()); - TCoord<RawPoint> dy = getY(second()) - getY(first()); + TCoord<P> dx = getX(second()) - getX(first()); + TCoord<P> dy = getY(second()) - getY(first()); double a = std::atan2(dy, dx); auto s = std::signbit(a); @@ -436,21 +437,48 @@ inline Radians _Segment<RawPoint>::angleToXaxis() const return angletox_; } -template<class RawPoint> +template<class P> template<class Unit> -inline Unit _Segment<RawPoint>::sqlength() const +inline Unit _Segment<P>::sqlength() const +{ + return pointlike::squaredDistance<P, Unit>(first(), second()); +} + +template<class T> +enable_if_t<std::is_floating_point<T>::value, T> modulo(const T &v, const T &m) { - return pointlike::squaredDistance<RawPoint, Unit>(first(), second()); + return 0; +} +template<class T> +enable_if_t<std::is_integral<T>::value, T> modulo(const T &v, const T &m) +{ + return v % m; +} + +template<class P> +inline _Box<P>::_Box(TCoord<P> width, TCoord<P> height, const P & center) : + PointPair<P>({center - P{width / 2, height / 2}, + center + P{width / 2, height / 2} + + P{modulo(width, TCoord<P>(2)), + modulo(height, TCoord<P>(2))}}) {} + +template<class P> +inline _Box<P>::_Box(const P& center) { + using C = TCoord<P>; + TCoord<P> M = std::max(getX(center), getY(center)) - + std::numeric_limits<C>::lowest(); + maxCorner() = center + P{M, M}; + minCorner() = center - P{M, M}; } -template<class RawPoint> -inline RawPoint _Box<RawPoint>::center() const BP2D_NOEXCEPT { +template<class P> +inline P _Box<P>::center() const BP2D_NOEXCEPT { auto& minc = minCorner(); auto& maxc = maxCorner(); - using Coord = TCoord<RawPoint>; + using Coord = TCoord<P>; - RawPoint ret = { // No rounding here, we dont know if these are int coords + P ret = { // No rounding here, we dont know if these are int coords Coord( (getX(minc) + getX(maxc)) / Coord(2) ), Coord( (getY(minc) + getY(maxc)) / Coord(2) ) }; @@ -467,76 +495,76 @@ enum class Formats { // used in friend declarations and can be aliased at class scope. namespace shapelike { -template<class RawShape> -inline RawShape create(const TContour<RawShape>& contour, - const THolesContainer<RawShape>& holes) +template<class S> +inline S create(const TContour<S>& contour, + const THolesContainer<S>& holes) { - return RawShape(contour, holes); + return S(contour, holes); } -template<class RawShape> -inline RawShape create(TContour<RawShape>&& contour, - THolesContainer<RawShape>&& holes) +template<class S> +inline S create(TContour<S>&& contour, + THolesContainer<S>&& holes) { - return RawShape(contour, holes); + return S(contour, holes); } -template<class RawShape> -inline RawShape create(const TContour<RawShape>& contour) +template<class S> +inline S create(const TContour<S>& contour) { - return create<RawShape>(contour, {}); + return create<S>(contour, {}); } -template<class RawShape> -inline RawShape create(TContour<RawShape>&& contour) +template<class S> +inline S create(TContour<S>&& contour) { - return create<RawShape>(contour, {}); + return create<S>(contour, {}); } -template<class RawShape> -inline THolesContainer<RawShape>& holes(RawShape& /*sh*/) +template<class S> +inline THolesContainer<S>& holes(S& /*sh*/) { - static THolesContainer<RawShape> empty; + static THolesContainer<S> empty; return empty; } -template<class RawShape> -inline const THolesContainer<RawShape>& holes(const RawShape& /*sh*/) +template<class S> +inline const THolesContainer<S>& holes(const S& /*sh*/) { - static THolesContainer<RawShape> empty; + static THolesContainer<S> empty; return empty; } -template<class RawShape> -inline TContour<RawShape>& hole(RawShape& sh, unsigned long idx) +template<class S> +inline TContour<S>& hole(S& sh, unsigned long idx) { return holes(sh)[idx]; } -template<class RawShape> -inline const TContour<RawShape>& hole(const RawShape& sh, unsigned long idx) +template<class S> +inline const TContour<S>& hole(const S& sh, unsigned long idx) { return holes(sh)[idx]; } -template<class RawShape> -inline size_t holeCount(const RawShape& sh) +template<class S> +inline size_t holeCount(const S& sh) { return holes(sh).size(); } -template<class RawShape> -inline TContour<RawShape>& contour(RawShape& sh) +template<class S> +inline TContour<S>& contour(S& sh) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::contour() unimplemented!"); return sh; } -template<class RawShape> -inline const TContour<RawShape>& contour(const RawShape& sh) +template<class S> +inline const TContour<S>& contour(const S& sh) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::contour() unimplemented!"); return sh; } @@ -548,71 +576,71 @@ inline void reserve(RawPath& p, size_t vertex_capacity, const PathTag&) p.reserve(vertex_capacity); } -template<class RawShape, class...Args> -inline void addVertex(RawShape& sh, const PathTag&, Args...args) +template<class S, class...Args> +inline void addVertex(S& sh, const PathTag&, Args...args) { sh.emplace_back(std::forward<Args>(args)...); } -template<class RawShape, class Fn> -inline void foreachVertex(RawShape& sh, Fn fn, const PathTag&) { +template<class S, class Fn> +inline void foreachVertex(S& sh, Fn fn, const PathTag&) { std::for_each(sh.begin(), sh.end(), fn); } -template<class RawShape> -inline typename RawShape::iterator begin(RawShape& sh, const PathTag&) +template<class S> +inline typename S::iterator begin(S& sh, const PathTag&) { return sh.begin(); } -template<class RawShape> -inline typename RawShape::iterator end(RawShape& sh, const PathTag&) +template<class S> +inline typename S::iterator end(S& sh, const PathTag&) { return sh.end(); } -template<class RawShape> -inline typename RawShape::const_iterator -cbegin(const RawShape& sh, const PathTag&) +template<class S> +inline typename S::const_iterator +cbegin(const S& sh, const PathTag&) { return sh.cbegin(); } -template<class RawShape> -inline typename RawShape::const_iterator -cend(const RawShape& sh, const PathTag&) +template<class S> +inline typename S::const_iterator +cend(const S& sh, const PathTag&) { return sh.cend(); } -template<class RawShape> -inline std::string toString(const RawShape& /*sh*/) +template<class S> +inline std::string toString(const S& /*sh*/) { return ""; } -template<Formats, class RawShape> -inline std::string serialize(const RawShape& /*sh*/, double /*scale*/=1) +template<Formats, class S> +inline std::string serialize(const S& /*sh*/, double /*scale*/=1) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::serialize() unimplemented!"); return ""; } -template<Formats, class RawShape> -inline void unserialize(RawShape& /*sh*/, const std::string& /*str*/) +template<Formats, class S> +inline void unserialize(S& /*sh*/, const std::string& /*str*/) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::unserialize() unimplemented!"); } template<class Cntr, class Unit = double> inline Unit area(const Cntr& poly, const PathTag& ); -template<class RawShape> -inline bool intersects(const RawShape& /*sh*/, const RawShape& /*sh*/) +template<class S> +inline bool intersects(const S& /*sh*/, const S& /*sh*/) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::intersects() unimplemented!"); return false; } @@ -633,29 +661,29 @@ inline bool isInside(const TGuest&, const THost&, return false; } -template<class RawShape> -inline bool touches( const RawShape& /*shape*/, - const RawShape& /*shape*/) +template<class S> +inline bool touches( const S& /*shape*/, + const S& /*shape*/) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::touches(shape, shape) unimplemented!"); return false; } -template<class RawShape> -inline bool touches( const TPoint<RawShape>& /*point*/, - const RawShape& /*shape*/) +template<class S> +inline bool touches( const TPoint<S>& /*point*/, + const S& /*shape*/) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::touches(point, shape) unimplemented!"); return false; } -template<class RawShape> -inline _Box<TPoint<RawShape>> boundingBox(const RawShape& /*sh*/, +template<class S> +inline _Box<TPoint<S>> boundingBox(const S& /*sh*/, const PathTag&) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::boundingBox(shape) unimplemented!"); } @@ -667,34 +695,34 @@ boundingBox(const RawShapes& /*sh*/, const MultiPolygonTag&) "shapelike::boundingBox(shapes) unimplemented!"); } -template<class RawShape> -inline RawShape convexHull(const RawShape& sh, const PathTag&); +template<class S> +inline S convexHull(const S& sh, const PathTag&); template<class RawShapes, class S = typename RawShapes::value_type> inline S convexHull(const RawShapes& sh, const MultiPolygonTag&); -template<class RawShape> -inline void rotate(RawShape& /*sh*/, const Radians& /*rads*/) +template<class S> +inline void rotate(S& /*sh*/, const Radians& /*rads*/) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::rotate() unimplemented!"); } -template<class RawShape, class RawPoint> -inline void translate(RawShape& /*sh*/, const RawPoint& /*offs*/) +template<class S, class P> +inline void translate(S& /*sh*/, const P& /*offs*/) { - static_assert(always_false<RawShape>::value, + static_assert(always_false<S>::value, "shapelike::translate() unimplemented!"); } -template<class RawShape> -inline void offset(RawShape& /*sh*/, TCoord<TPoint<RawShape>> /*distance*/) +template<class S> +inline void offset(S& /*sh*/, TCoord<TPoint<S>> /*distance*/) { dout() << "The current geometry backend does not support offsetting!\n"; } -template<class RawShape> -inline std::pair<bool, std::string> isValid(const RawShape& /*sh*/) +template<class S> +inline std::pair<bool, std::string> isValid(const S& /*sh*/) { return {false, "shapelike::isValid() unimplemented!"}; } @@ -735,56 +763,56 @@ template<class RawPath> inline bool isConvex(const RawPath& sh, const PathTag&) // No need to implement these // ***************************************************************************** -template<class RawShape> -inline typename TContour<RawShape>::iterator -begin(RawShape& sh, const PolygonTag&) +template<class S> +inline typename TContour<S>::iterator +begin(S& sh, const PolygonTag&) { return begin(contour(sh), PathTag()); } -template<class RawShape> // Tag dispatcher -inline auto begin(RawShape& sh) -> decltype(begin(sh, Tag<RawShape>())) +template<class S> // Tag dispatcher +inline auto begin(S& sh) -> decltype(begin(sh, Tag<S>())) { - return begin(sh, Tag<RawShape>()); + return begin(sh, Tag<S>()); } -template<class RawShape> -inline typename TContour<RawShape>::const_iterator -cbegin(const RawShape& sh, const PolygonTag&) +template<class S> +inline typename TContour<S>::const_iterator +cbegin(const S& sh, const PolygonTag&) { return cbegin(contour(sh), PathTag()); } -template<class RawShape> // Tag dispatcher -inline auto cbegin(const RawShape& sh) -> decltype(cbegin(sh, Tag<RawShape>())) +template<class S> // Tag dispatcher +inline auto cbegin(const S& sh) -> decltype(cbegin(sh, Tag<S>())) { - return cbegin(sh, Tag<RawShape>()); + return cbegin(sh, Tag<S>()); } -template<class RawShape> -inline typename TContour<RawShape>::iterator -end(RawShape& sh, const PolygonTag&) +template<class S> +inline typename TContour<S>::iterator +end(S& sh, const PolygonTag&) { return end(contour(sh), PathTag()); } -template<class RawShape> // Tag dispatcher -inline auto end(RawShape& sh) -> decltype(begin(sh, Tag<RawShape>())) +template<class S> // Tag dispatcher +inline auto end(S& sh) -> decltype(begin(sh, Tag<S>())) { - return end(sh, Tag<RawShape>()); + return end(sh, Tag<S>()); } -template<class RawShape> -inline typename TContour<RawShape>::const_iterator -cend(const RawShape& sh, const PolygonTag&) +template<class S> +inline typename TContour<S>::const_iterator +cend(const S& sh, const PolygonTag&) { return cend(contour(sh), PathTag()); } -template<class RawShape> // Tag dispatcher -inline auto cend(const RawShape& sh) -> decltype(cend(sh, Tag<RawShape>())) +template<class S> // Tag dispatcher +inline auto cend(const S& sh) -> decltype(cend(sh, Tag<S>())) { - return cend(sh, Tag<RawShape>()); + return cend(sh, Tag<S>()); } template<class It> std::reverse_iterator<It> _backward(It iter) { @@ -817,8 +845,8 @@ template<class P> TPoint<P> back (const P& p) { } // Optional, does nothing by default -template<class RawShape> -inline void reserve(RawShape& sh, size_t vertex_capacity, const PolygonTag&) +template<class S> +inline void reserve(S& sh, size_t vertex_capacity, const PolygonTag&) { reserve(contour(sh), vertex_capacity, PathTag()); } @@ -828,20 +856,20 @@ inline void reserve(T& sh, size_t vertex_capacity) { reserve(sh, vertex_capacity, Tag<T>()); } -template<class RawShape, class...Args> -inline void addVertex(RawShape& sh, const PolygonTag&, Args...args) +template<class S, class...Args> +inline void addVertex(S& sh, const PolygonTag&, Args...args) { addVertex(contour(sh), PathTag(), std::forward<Args>(args)...); } -template<class RawShape, class...Args> // Tag dispatcher -inline void addVertex(RawShape& sh, Args...args) +template<class S, class...Args> // Tag dispatcher +inline void addVertex(S& sh, Args...args) { - addVertex(sh, Tag<RawShape>(), std::forward<Args>(args)...); + addVertex(sh, Tag<S>(), std::forward<Args>(args)...); } -template<class RawShape> -inline _Box<TPoint<RawShape>> boundingBox(const RawShape& poly, const PolygonTag&) +template<class S> +inline _Box<TPoint<S>> boundingBox(const S& poly, const PolygonTag&) { return boundingBox(contour(poly), PathTag()); } @@ -938,40 +966,40 @@ template<class S> inline double area(const S& poly, const PolygonTag& ) }); } -template<class RawShape> // Dispatching function -inline double area(const RawShape& sh) +template<class S> // Dispatching function +inline double area(const S& sh) { - return area(sh, Tag<RawShape>()); + return area(sh, Tag<S>()); } template<class RawShapes> inline double area(const RawShapes& shapes, const MultiPolygonTag&) { - using RawShape = typename RawShapes::value_type; + using S = typename RawShapes::value_type; return std::accumulate(shapes.begin(), shapes.end(), 0.0, - [](double a, const RawShape& b) { + [](double a, const S& b) { return a += area(b); }); } -template<class RawShape> -inline RawShape convexHull(const RawShape& sh, const PolygonTag&) +template<class S> +inline S convexHull(const S& sh, const PolygonTag&) { - return create<RawShape>(convexHull(contour(sh), PathTag())); + return create<S>(convexHull(contour(sh), PathTag())); } -template<class RawShape> -inline auto convexHull(const RawShape& sh) - -> decltype(convexHull(sh, Tag<RawShape>())) // TODO: C++14 could deduce +template<class S> +inline auto convexHull(const S& sh) + -> decltype(convexHull(sh, Tag<S>())) // TODO: C++14 could deduce { - return convexHull(sh, Tag<RawShape>()); + return convexHull(sh, Tag<S>()); } -template<class RawShape> -inline RawShape convexHull(const RawShape& sh, const PathTag&) +template<class S> +inline S convexHull(const S& sh, const PathTag&) { - using Unit = TCompute<RawShape>; - using Point = TPoint<RawShape>; + using Unit = TCompute<S>; + using Point = TPoint<S>; namespace sl = shapelike; size_t edges = sl::cend(sh) - sl::cbegin(sh); @@ -1016,8 +1044,8 @@ inline RawShape convexHull(const RawShape& sh, const PathTag&) ++ik; } - RawShape ret; reserve(ret, U.size() + L.size()); - if(is_clockwise<RawShape>()) { + S ret; reserve(ret, U.size() + L.size()); + if(is_clockwise<S>()) { for(auto it = U.begin(); it != std::prev(U.end()); ++it) addVertex(ret, *it); for(auto it = L.rbegin(); it != std::prev(L.rend()); ++it) @@ -1068,11 +1096,11 @@ inline bool isInside(const TP& point, const TB& box, return px > minx && px < maxx && py > miny && py < maxy; } -template<class RawShape, class TC> -inline bool isInside(const RawShape& sh, const TC& circ, +template<class S, class TC> +inline bool isInside(const S& sh, const TC& circ, const PolygonTag&, const CircleTag&) { - return std::all_of(cbegin(sh), cend(sh), [&circ](const TPoint<RawShape>& p) + return std::all_of(cbegin(sh), cend(sh), [&circ](const TPoint<S>& p) { return isInside(p, circ, PointTag(), CircleTag()); }); @@ -1103,8 +1131,8 @@ inline bool isInside(const TBGuest& ibb, const TBHost& box, return iminX > minX && imaxX < maxX && iminY > minY && imaxY < maxY; } -template<class RawShape, class TB> -inline bool isInside(const RawShape& poly, const TB& box, +template<class S, class TB> +inline bool isInside(const S& poly, const TB& box, const PolygonTag&, const BoxTag&) { return isInside(boundingBox(poly), box, BoxTag(), BoxTag()); @@ -1115,36 +1143,36 @@ inline bool isInside(const TGuest& guest, const THost& host) { return isInside(guest, host, Tag<TGuest>(), Tag<THost>()); } -template<class RawShape> // Potential O(1) implementation may exist -inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx, +template<class S> // Potential O(1) implementation may exist +inline TPoint<S>& vertex(S& sh, unsigned long idx, const PolygonTag&) { return *(shapelike::begin(contour(sh)) + idx); } -template<class RawShape> // Potential O(1) implementation may exist -inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx, +template<class S> // Potential O(1) implementation may exist +inline TPoint<S>& vertex(S& sh, unsigned long idx, const PathTag&) { return *(shapelike::begin(sh) + idx); } -template<class RawShape> // Potential O(1) implementation may exist -inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx) +template<class S> // Potential O(1) implementation may exist +inline TPoint<S>& vertex(S& sh, unsigned long idx) { - return vertex(sh, idx, Tag<RawShape>()); + return vertex(sh, idx, Tag<S>()); } -template<class RawShape> // Potential O(1) implementation may exist -inline const TPoint<RawShape>& vertex(const RawShape& sh, +template<class S> // Potential O(1) implementation may exist +inline const TPoint<S>& vertex(const S& sh, unsigned long idx, const PolygonTag&) { return *(shapelike::cbegin(contour(sh)) + idx); } -template<class RawShape> // Potential O(1) implementation may exist -inline const TPoint<RawShape>& vertex(const RawShape& sh, +template<class S> // Potential O(1) implementation may exist +inline const TPoint<S>& vertex(const S& sh, unsigned long idx, const PathTag&) { @@ -1152,28 +1180,28 @@ inline const TPoint<RawShape>& vertex(const RawShape& sh, } -template<class RawShape> // Potential O(1) implementation may exist -inline const TPoint<RawShape>& vertex(const RawShape& sh, +template<class S> // Potential O(1) implementation may exist +inline const TPoint<S>& vertex(const S& sh, unsigned long idx) { - return vertex(sh, idx, Tag<RawShape>()); + return vertex(sh, idx, Tag<S>()); } -template<class RawShape> -inline size_t contourVertexCount(const RawShape& sh) +template<class S> +inline size_t contourVertexCount(const S& sh) { return shapelike::cend(sh) - shapelike::cbegin(sh); } -template<class RawShape, class Fn> -inline void foreachVertex(RawShape& sh, Fn fn, const PolygonTag&) { +template<class S, class Fn> +inline void foreachVertex(S& sh, Fn fn, const PolygonTag&) { foreachVertex(contour(sh), fn, PathTag()); for(auto& h : holes(sh)) foreachVertex(h, fn, PathTag()); } -template<class RawShape, class Fn> -inline void foreachVertex(RawShape& sh, Fn fn) { - foreachVertex(sh, fn, Tag<RawShape>()); +template<class S, class Fn> +inline void foreachVertex(S& sh, Fn fn) { + foreachVertex(sh, fn, Tag<S>()); } template<class Poly> inline bool isConvex(const Poly& sh, const PolygonTag&) @@ -1184,9 +1212,9 @@ template<class Poly> inline bool isConvex(const Poly& sh, const PolygonTag&) return convex; } -template<class RawShape> inline bool isConvex(const RawShape& sh) // dispatch +template<class S> inline bool isConvex(const S& sh) // dispatch { - return isConvex(sh, Tag<RawShape>()); + return isConvex(sh, Tag<S>()); } } |