Skip to content

Commit

Permalink
polygon offsets: scale arc tolerance width offset distance
Browse files Browse the repository at this point in the history
  • Loading branch information
Piezoid committed Sep 1, 2022
1 parent 29ab836 commit 4d81c52
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 13 deletions.
9 changes: 6 additions & 3 deletions include/utils/polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class ListPolyIt;
typedef std::list<Point> ListPolygon; //!< A polygon represented by a linked list instead of a vector
typedef std::vector<ListPolygon> ListPolygons; //!< Polygons represented by a vector of linked lists instead of a vector of vectors

// Allowed deviation for round joint while offsetting (this reduces the number of segment, http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm)
static constexpr double clipper_arc_tolerance = INT_EPSILON;
// How far a miter can be offseted before being truncated, relative to the offset size (http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/MiterLimit.htm)
static constexpr double clipper_miter_limit = 1.2;
static constexpr int clipper_init = 0;
Expand Down Expand Up @@ -398,6 +396,11 @@ class ConstPolygonRef
* \param[in,out] backward_is_too_far Whether trying another step backward is blocked by the shortcut length condition. Updated for the next iteration.
*/
static void smooth_outward_step(const Point p1, const int64_t shortcut_length2, ListPolyIt& p0_it, ListPolyIt& p2_it, bool& forward_is_blocked, bool& backward_is_blocked, bool& forward_is_too_far, bool& backward_is_too_far);


/// Allowed deviation for round joints while offsetting (this reduces the number of segment
/// @see http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
static double calcArcTolerance(int offset);
};


Expand Down Expand Up @@ -1014,7 +1017,7 @@ class Polygons
{
Polygons ret;
ClipperLib::EndType end_type = (joinType == ClipperLib::jtMiter)? ClipperLib::etOpenSquare : ClipperLib::etOpenRound;
ClipperLib::ClipperOffset clipper(clipper_miter_limit, clipper_arc_tolerance);
ClipperLib::ClipperOffset clipper(clipper_miter_limit, ConstPolygonRef::calcArcTolerance(distance));
clipper.AddPaths(paths, joinType, end_type);
clipper.MiterLimit = clipper_miter_limit;
clipper.Execute(ret.paths, distance);
Expand Down
24 changes: 14 additions & 10 deletions src/utils/polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Polygons Polygons::approxConvexHull(int extra_outset)
for (const ClipperLib::Path& path : paths)
{
Polygons offset_result;
ClipperLib::ClipperOffset offsetter(clipper_miter_limit, clipper_arc_tolerance);
ClipperLib::ClipperOffset offsetter(clipper_miter_limit, ConstPolygonRef::calcArcTolerance(overshoot));
offsetter.AddPath(path, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
offsetter.Execute(offset_result.paths, overshoot);
convex_hull.add(offset_result);
Expand Down Expand Up @@ -281,7 +281,7 @@ Polygons Polygons::intersectionPolyLines(const Polygons& polylines, bool restitc
if (restitch)
{
Polygons result_lines, result_polygons;
const coord_t snap_distance = clipper_arc_tolerance;
const coord_t snap_distance = INT_EPSILON;
PolylineStitcher<Polygons, Polygon, Point>::stitch(ret, result_lines, result_polygons, max_stitch_distance, snap_distance);
ret = result_lines;
// if polylines got stitched into polygons, split them back up into a polyline again, because the result only admits polylines
Expand Down Expand Up @@ -339,30 +339,34 @@ coord_t Polygons::polyLineLength() const

Polygons Polygons::offset(int distance, ClipperLib::JoinType join_type, double miter_limit) const
{
if (distance == 0)
if (std::abs(distance) < INT_EPSILON / 2)
{
return *this;
}
Polygons ret;
ClipperLib::ClipperOffset clipper(miter_limit, clipper_arc_tolerance);
ClipperLib::ClipperOffset clipper(miter_limit, ConstPolygonRef::calcArcTolerance(distance));
clipper.AddPaths(unionPolygons().paths, join_type, ClipperLib::etClosedPolygon);
clipper.MiterLimit = miter_limit;
assert(clipper.MiterLimit == miter_limit);
clipper.Execute(ret.paths, distance);
return ret;
}

double ConstPolygonRef::calcArcTolerance(int offset) {
constexpr double min_tol = std::max<double>(5_mu, INT_EPSILON);
return std::max(min_tol, std::abs(static_cast<double>(offset)) * 1e-2);
}

Polygons ConstPolygonRef::offset(int distance, ClipperLib::JoinType join_type, double miter_limit) const
{
if (distance == 0)
Polygons ret;
if (std::abs(distance) < INT_EPSILON / 2)
{
Polygons ret;
ret.add(*this);
return ret;
}
Polygons ret;
ClipperLib::ClipperOffset clipper(miter_limit, clipper_arc_tolerance);
ClipperLib::ClipperOffset clipper(miter_limit, calcArcTolerance(distance));
clipper.AddPath(*path, join_type, ClipperLib::etClosedPolygon);
clipper.MiterLimit = miter_limit;
assert(clipper.MiterLimit == miter_limit);
clipper.Execute(ret.paths, distance);
return ret;
}
Expand Down

0 comments on commit 4d81c52

Please sign in to comment.