|
|
@ -24,7 +24,7 @@ namespace Clipper2Lib { |
|
|
|
|
|
|
|
inline Paths64 BooleanOp(ClipType cliptype, FillRule fillrule, |
|
|
|
const Paths64& subjects, const Paths64& clips) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Paths64 result; |
|
|
|
Clipper64 clipper; |
|
|
|
clipper.AddSubject(subjects); |
|
|
@ -58,7 +58,7 @@ namespace Clipper2Lib { |
|
|
|
} |
|
|
|
|
|
|
|
inline void BooleanOp(ClipType cliptype, FillRule fillrule, |
|
|
|
const PathsD& subjects, const PathsD& clips, |
|
|
|
const PathsD& subjects, const PathsD& clips, |
|
|
|
PolyTreeD& polytree, int precision = 2) |
|
|
|
{ |
|
|
|
polytree.Clear(); |
|
|
@ -75,7 +75,7 @@ namespace Clipper2Lib { |
|
|
|
{ |
|
|
|
return BooleanOp(ClipType::Intersection, fillrule, subjects, clips); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
inline PathsD Intersect(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) |
|
|
|
{ |
|
|
|
return BooleanOp(ClipType::Intersection, fillrule, subjects, clips, decimal_prec); |
|
|
@ -145,7 +145,7 @@ namespace Clipper2Lib { |
|
|
|
} |
|
|
|
|
|
|
|
inline PathsD InflatePaths(const PathsD& paths, double delta, |
|
|
|
JoinType jt, EndType et, double miter_limit = 2.0, |
|
|
|
JoinType jt, EndType et, double miter_limit = 2.0, |
|
|
|
int precision = 2, double arc_tolerance = 0.0) |
|
|
|
{ |
|
|
|
int error_code = 0; |
|
|
@ -197,7 +197,7 @@ namespace Clipper2Lib { |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
inline Paths64 RectClip(const Rect64& rect, |
|
|
|
inline Paths64 ExecuteRectClip(const Rect64& rect, |
|
|
|
const Paths64& paths, bool convex_only = false) |
|
|
|
{ |
|
|
|
if (rect.IsEmpty() || paths.empty()) return Paths64(); |
|
|
@ -205,7 +205,7 @@ namespace Clipper2Lib { |
|
|
|
return rc.Execute(paths, convex_only); |
|
|
|
} |
|
|
|
|
|
|
|
inline Paths64 RectClip(const Rect64& rect, |
|
|
|
inline Paths64 ExecuteRectClip(const Rect64& rect, |
|
|
|
const Path64& path, bool convex_only = false) |
|
|
|
{ |
|
|
|
if (rect.IsEmpty() || path.empty()) return Paths64(); |
|
|
@ -213,7 +213,7 @@ namespace Clipper2Lib { |
|
|
|
return rc.Execute(Paths64{ path }, convex_only); |
|
|
|
} |
|
|
|
|
|
|
|
inline PathsD RectClip(const RectD& rect, |
|
|
|
inline PathsD ExecuteRectClip(const RectD& rect, |
|
|
|
const PathsD& paths, bool convex_only = false, int precision = 2) |
|
|
|
{ |
|
|
|
if (rect.IsEmpty() || paths.empty()) return PathsD(); |
|
|
@ -224,35 +224,35 @@ namespace Clipper2Lib { |
|
|
|
Rect64 r = ScaleRect<int64_t, double>(rect, scale); |
|
|
|
class RectClip rc(r); |
|
|
|
Paths64 pp = ScalePaths<int64_t, double>(paths, scale, error_code); |
|
|
|
if (error_code) return PathsD(); // ie: error_code result is lost |
|
|
|
if (error_code) return PathsD(); // ie: error_code result is lost |
|
|
|
return ScalePaths<double, int64_t>( |
|
|
|
rc.Execute(pp, convex_only), 1 / scale, error_code); |
|
|
|
} |
|
|
|
|
|
|
|
inline PathsD RectClip(const RectD& rect, |
|
|
|
inline PathsD ExecuteRectClip(const RectD& rect, |
|
|
|
const PathD& path, bool convex_only = false, int precision = 2) |
|
|
|
{ |
|
|
|
return RectClip(rect, PathsD{ path }, convex_only, precision); |
|
|
|
return ExecuteRectClip(rect, PathsD{ path }, convex_only, precision); |
|
|
|
} |
|
|
|
|
|
|
|
inline Paths64 RectClipLines(const Rect64& rect, const Paths64& lines) |
|
|
|
inline Paths64 ExecuteRectClipLines(const Rect64& rect, const Paths64& lines) |
|
|
|
{ |
|
|
|
if (rect.IsEmpty() || lines.empty()) return Paths64(); |
|
|
|
class RectClipLines rcl(rect); |
|
|
|
return rcl.Execute(lines); |
|
|
|
} |
|
|
|
|
|
|
|
inline Paths64 RectClipLines(const Rect64& rect, const Path64& line) |
|
|
|
inline Paths64 ExecuteRectClipLines(const Rect64& rect, const Path64& line) |
|
|
|
{ |
|
|
|
return RectClipLines(rect, Paths64{ line }); |
|
|
|
return ExecuteRectClipLines(rect, Paths64{ line }); |
|
|
|
} |
|
|
|
|
|
|
|
inline PathsD RectClipLines(const RectD& rect, const PathD& line, int precision = 2) |
|
|
|
inline PathsD ExecuteRectClipLines(const RectD& rect, const PathD& line, int precision = 2) |
|
|
|
{ |
|
|
|
return RectClip(rect, PathsD{ line }, precision); |
|
|
|
return ExecuteRectClip(rect, PathsD{ line }, precision); |
|
|
|
} |
|
|
|
|
|
|
|
inline PathsD RectClipLines(const RectD& rect, const PathsD& lines, int precision = 2) |
|
|
|
inline PathsD ExecuteRectClipLines(const RectD& rect, const PathsD& lines, int precision = 2) |
|
|
|
{ |
|
|
|
if (rect.IsEmpty() || lines.empty()) return PathsD(); |
|
|
|
int error_code = 0; |
|
|
@ -316,7 +316,7 @@ namespace Clipper2Lib { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static void OutlinePolyPath(std::ostream& os, |
|
|
|
static void OutlinePolyPath(std::ostream& os, |
|
|
|
bool isHole, size_t count, const std::string& preamble) |
|
|
|
{ |
|
|
|
std::string plural = (count == 1) ? "." : "s."; |
|
|
@ -366,7 +366,7 @@ namespace Clipper2Lib { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} // end details namespace |
|
|
|
} // end details namespace |
|
|
|
|
|
|
|
inline std::ostream& operator<< (std::ostream& os, const PolyTree64& pp) |
|
|
|
{ |
|
|
@ -409,7 +409,7 @@ namespace Clipper2Lib { |
|
|
|
inline bool CheckPolytreeFullyContainsChildren(const PolyTree64& polytree) |
|
|
|
{ |
|
|
|
for (const auto& child : polytree) |
|
|
|
if (child->Count() > 0 && |
|
|
|
if (child->Count() > 0 && |
|
|
|
!details::PolyPath64ContainsChildren(*child)) |
|
|
|
return false; |
|
|
|
return true; |
|
|
@ -574,12 +574,12 @@ namespace Clipper2Lib { |
|
|
|
double cp = std::abs(CrossProduct(pt1, pt2, pt3)); |
|
|
|
return (cp * cp) / (DistanceSqr(pt1, pt2) * DistanceSqr(pt2, pt3)) < sin_sqrd_min_angle_rads; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
inline Path<T> Ellipse(const Rect<T>& rect, int steps = 0) |
|
|
|
{ |
|
|
|
return Ellipse(rect.MidPoint(), |
|
|
|
static_cast<double>(rect.Width()) *0.5, |
|
|
|
return Ellipse(rect.MidPoint(), |
|
|
|
static_cast<double>(rect.Width()) *0.5, |
|
|
|
static_cast<double>(rect.Height()) * 0.5, steps); |
|
|
|
} |
|
|
|
|
|
|
@ -620,7 +620,7 @@ namespace Clipper2Lib { |
|
|
|
return Sqr(a * d - c * b) / (c * c + d * d); |
|
|
|
} |
|
|
|
|
|
|
|
inline size_t GetNext(size_t current, size_t high, |
|
|
|
inline size_t GetNext(size_t current, size_t high, |
|
|
|
const std::vector<bool>& flags) |
|
|
|
{ |
|
|
|
++current; |
|
|
@ -631,7 +631,7 @@ namespace Clipper2Lib { |
|
|
|
return current; |
|
|
|
} |
|
|
|
|
|
|
|
inline size_t GetPrior(size_t current, size_t high, |
|
|
|
inline size_t GetPrior(size_t current, size_t high, |
|
|
|
const std::vector<bool>& flags) |
|
|
|
{ |
|
|
|
if (current == 0) current = high; |
|
|
@ -644,7 +644,7 @@ namespace Clipper2Lib { |
|
|
|
} |
|
|
|
|
|
|
|
template <typename T> |
|
|
|
inline Path<T> SimplifyPath(const Path<T> path, |
|
|
|
inline Path<T> SimplifyPath(const Path<T> path, |
|
|
|
double epsilon, bool isOpenPath = false) |
|
|
|
{ |
|
|
|
const size_t len = path.size(), high = len -1; |
|
|
@ -659,7 +659,7 @@ namespace Clipper2Lib { |
|
|
|
distSqr[0] = MAX_DBL; |
|
|
|
distSqr[high] = MAX_DBL; |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
distSqr[0] = PerpendicDistFromLineSqrd(path[0], path[high], path[1]); |
|
|
|
distSqr[high] = PerpendicDistFromLineSqrd(path[high], path[0], path[high - 1]); |
|
|
@ -678,7 +678,7 @@ namespace Clipper2Lib { |
|
|
|
} while (curr != start && distSqr[curr] > epsSqr); |
|
|
|
if (curr == start) break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
prior = GetPrior(curr, high, flags); |
|
|
|
next = GetNext(curr, high, flags); |
|
|
|
if (next == prior) break; |
|
|
@ -712,7 +712,7 @@ namespace Clipper2Lib { |
|
|
|
} |
|
|
|
|
|
|
|
template <typename T> |
|
|
|
inline Paths<T> SimplifyPaths(const Paths<T> paths, |
|
|
|
inline Paths<T> SimplifyPaths(const Paths<T> paths, |
|
|
|
double epsilon, bool isOpenPath = false) |
|
|
|
{ |
|
|
|
Paths<T> result; |
|
|
|