You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
1.9 KiB
C

1 month ago
#include <memory>
#include <vector>
#include "DrawOperator/CurveEx.h"
#include "clipper2/clipper.h"
#include "PolygonUtils.h"
/**
* <EFBFBD><EFBFBD>϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class GapDetection
{
public:
GapDetection() = default;
~GapDetection() = default;
struct Gap
{
std::unique_ptr<CCurveEx> pArea;
CCurveEx* pFirstCurve;
CCurveEx* pSecondCurve;
};
double GetGapValue() const
{
return minGap;
}
void SetGapValue(double value)
{
minGap = value;
}
std::vector<Gap> DetectGaps(const std::vector<CCurveEx*>& curves) const
{
std::vector<Gap> allGaps;
const size_t numCurves = curves.size();
if (numCurves < 2)
{
return allGaps;
}
std::vector<Clipper2Lib::PathD> 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<Gap> SolutionToGap(Clipper2Lib::PathsD& solution, CCurveEx* pFirst, CCurveEx* pSecond) const
{
std::vector<Gap> result;
for (const auto& solutionPath : solution)
{
std::unique_ptr<CCurveEx> 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;
};