Skip to content

Commit

Permalink
Fixed a minor (C++) bug in open path clipping when using Z (#525)
Browse files Browse the repository at this point in the history
  • Loading branch information
AngusJohnson committed May 20, 2023
1 parent f3fd560 commit 9d50a82
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 29 deletions.
20 changes: 11 additions & 9 deletions CPP/Clipper2Lib/src/clipper.engine.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 16 May 2023 *
* Date : 20 May 2023 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Purpose : This is the main polygon clipping module *
Expand Down Expand Up @@ -1659,17 +1659,14 @@ namespace Clipper2Lib {
default: if (std::abs(edge_c->wind_cnt) != 1) return nullptr; break;
}

OutPt* resultOp;
//toggle contribution ...
if (IsHotEdge(*edge_o))
{
OutPt* resultOp = AddOutPt(*edge_o, pt);
#ifdef USINGZ
if (zCallback_) SetZ(e1, e2, resultOp->pt);
#endif
resultOp = AddOutPt(*edge_o, pt);
if (IsFront(*edge_o)) edge_o->outrec->front_edge = nullptr;
else edge_o->outrec->back_edge = nullptr;
edge_o->outrec = nullptr;
return resultOp;
}

//horizontal edges can pass under open paths at a LocMins
Expand All @@ -1689,11 +1686,16 @@ namespace Clipper2Lib {
return e3->outrec->pts;
}
else
return StartOpenPath(*edge_o, pt);
resultOp = StartOpenPath(*edge_o, pt);
}
else
return StartOpenPath(*edge_o, pt);
}
resultOp = StartOpenPath(*edge_o, pt);

#ifdef USINGZ
if (zCallback_) SetZ(*edge_o, *edge_c, resultOp->pt);
#endif
return resultOp;
} // end of an open path intersection

//MANAGING CLOSED PATHS FROM HERE ON

Expand Down
40 changes: 20 additions & 20 deletions CPP/Clipper2Lib/src/clipper.offset.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 15 May 2023 *
* Date : 17 May 2023 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Purpose : Path Offset (Inflate/Shrink) *
Expand Down Expand Up @@ -325,8 +325,10 @@ void ClipperOffset::OffsetPoint(Group& group, Path64& path, size_t j, size_t k)
return;
}

if (cos_a > 0.99) // 0.99 ~= 8.1 deg.
if (cos_a > 0.999) // almost straight - less than 2.5 degree (#424)
{
DoMiter(group, path, j, k, cos_a);
}
else if (cos_a > -0.99 && (sin_a * group_delta_ < 0))
{
// is concave
Expand All @@ -342,7 +344,7 @@ void ClipperOffset::OffsetPoint(Group& group, Path64& path, size_t j, size_t k)
if (cos_a > temp_lim_ - 1) DoMiter(group, path, j, k, cos_a);
else DoSquare(group, path, j, k);
}
else if (join_type_ == JoinType::Square)
else if (cos_a > 0.99 || join_type_ == JoinType::Square) // 0.99 ~= 8.1 deg.
DoSquare(group, path, j, k);
else
DoRound(group, path, j, k, std::atan2(sin_a, cos_a));
Expand Down Expand Up @@ -485,25 +487,23 @@ void ClipperOffset::DoGroupOffset(Group& group)
join_type_ = group.join_type;
end_type_ = group.end_type;

//calculate a sensible number of steps (for 360 deg for the given offset
if (group.join_type == JoinType::Round || group.end_type == EndType::Round)
if (!deltaCallback64_ &&
(group.join_type == JoinType::Round || group.end_type == EndType::Round))
{
//calculate a sensible number of steps (for 360 deg for the given offset)
// arcTol - when arc_tolerance_ is undefined (0), the amount of
// curve imprecision that's allowed is based on the size of the
// offset (delta). Obviously very large offsets will almost always
// require much less precision. See also offset_triginometry2.svg
double arcTol = (arc_tolerance_ > floating_point_tolerance ?
std::min(abs_delta, arc_tolerance_) :
std::log10(2 + abs_delta) * default_arc_tolerance);

if (!deltaCallback64_) {
// arcTol - when arc_tolerance_ is undefined (0), the amount of
// curve imprecision that's allowed is based on the size of the
// offset (delta). Obviously very large offsets will almost always
// require much less precision. See also offset_triginometry2.svg
double arcTol = (arc_tolerance_ > floating_point_tolerance ?
std::min(abs_delta, arc_tolerance_) :
std::log10(2 + abs_delta) * default_arc_tolerance);

double steps_per_360 = std::min(PI / std::acos(1 - arcTol / abs_delta), abs_delta * PI);
step_sin_ = std::sin(2 * PI / steps_per_360);
step_cos_ = std::cos(2 * PI / steps_per_360);
if (group_delta_ < 0.0) step_sin_ = -step_sin_;
steps_per_rad_ = steps_per_360 / (2 * PI);
}
double steps_per_360 = std::min(PI / std::acos(1 - arcTol / abs_delta), abs_delta * PI);
step_sin_ = std::sin(2 * PI / steps_per_360);
step_cos_ = std::cos(2 * PI / steps_per_360);
if (group_delta_ < 0.0) step_sin_ = -step_sin_;
steps_per_rad_ = steps_per_360 / (2 * PI);
}

bool is_joined =
Expand Down

0 comments on commit 9d50a82

Please sign in to comment.