#include #include #include "DrawOperator/CurveEx.h" #include "clipper2/clipper.h" #include "PolygonUtils.h" /** * ·ì϶¼ì²â */ class GapDetection { public: GapDetection() = default; ~GapDetection() = default; struct Gap { std::unique_ptr pArea; CCurveEx* pFirstCurve; CCurveEx* pSecondCurve; }; double GetGapValue() const { return minGap; } void SetGapValue(double value) { minGap = value; } std::vector DetectGaps(const std::vector& curves) const { std::vector allGaps; const size_t numCurves = curves.size(); if (numCurves < 2) { return allGaps; } 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::FindGapRegions(path1, path2, minGap); auto result = SolutionToGap(solution, curves[i], curves[j]); allGaps.insert(allGaps.end(), std::make_move_iterator(result.begin()), std::make_move_iterator(result.end())); } } return allGaps; } private: std::vector SolutionToGap(Clipper2Lib::PathsD& solution, CCurveEx* pFirst, CCurveEx* pSecond) const { std::vector result; for (const auto& solutionPath : solution) { std::unique_ptr pGapArea = PolygonUtils::ConvertPathToClosedCurve(solutionPath); if (pGapArea) { Gap overlap; overlap.pArea = std::move(pGapArea); overlap.pFirstCurve = pFirst; overlap.pSecondCurve = pSecond; result.push_back(std::move(overlap)); } } return result; } double minGap = 20.0; };