#include #include #include "DrawOperator/CurveEx.h" #include "clipper2/clipper.h" #include "PolygonUtils.h" /** * 重叠检测类 */ class OverlapDetection { public: OverlapDetection() = default; ~OverlapDetection() = default; struct Overlap { std::unique_ptr pArea; CCurveEx* pFirstCurve; CCurveEx* pSecondCurve; }; /** * 检测哪些曲线有交集 * * \param curves 参与运算的所有曲线,如果没闭合,会当闭合曲线处理 * \return 返回曲线的交集 */ std::vector DetectOverlap(const std::vector& curves) const { std::vector allOverlaps; const size_t numCurves = curves.size(); if (numCurves < 2) { return allOverlaps; } std::vector cachedPaths; cachedPaths.reserve(numCurves); for (size_t i = 0; i < numCurves; i++) { cachedPaths.push_back(PolygonUtils::ConvertCurveToPath(curves[i])); } for (size_t i = 0; i < numCurves; i++) { for (size_t j = i + 1; j < numCurves; j++) { const Clipper2Lib::PathD& path1 = cachedPaths[i]; const Clipper2Lib::PathD& path2 = cachedPaths[j]; if (path1.size() < 3 || path2.size() < 3) { continue; } Clipper2Lib::PathsD solution = PolygonUtils::Intersect(path1, path2); auto result = SolutionToOverlap(solution, curves, curves[i], curves[j]); allOverlaps.insert(allOverlaps.end(), std::make_move_iterator(result.begin()), std::make_move_iterator(result.end())); } } return allOverlaps; } private: std::vector SolutionToOverlap(Clipper2Lib::PathsD& solution, const std::vector& curves, CCurveEx* pFirst, CCurveEx* pSecond) const { std::vector result; for (const auto& solutionPath : solution) { std::unique_ptr pOverlapArea = PolygonUtils::ConvertPathToClosedCurve(solutionPath); if (pOverlapArea) { Overlap overlap; overlap.pArea = std::move(pOverlapArea); overlap.pFirstCurve = pFirst; overlap.pSecondCurve = pSecond; result.push_back(std::move(overlap)); } } return result; } };