|
|
|
|
|
#include <memory>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include "DrawOperator/CurveEx.h"
|
|
|
|
|
|
#include "clipper2/clipper.h"
|
|
|
|
|
|
#include "PolygonUtils.h"
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
class OverlapDetection
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
OverlapDetection() = default;
|
|
|
|
|
|
~OverlapDetection() = default;
|
|
|
|
|
|
|
|
|
|
|
|
struct Overlap
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<CCurveEx> pArea;
|
|
|
|
|
|
CCurveEx* pFirstCurve;
|
|
|
|
|
|
CCurveEx* pSecondCurve;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param curves <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>պϣ<EFBFBD><EFBFBD>ᵱ<EFBFBD>պ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵĽ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::vector<Overlap> DetectOverlap(const std::vector<CCurveEx*>& curves) const
|
|
|
|
|
|
{
|
|
|
|
|
|
std::vector<Overlap> allOverlaps;
|
|
|
|
|
|
const size_t numCurves = curves.size();
|
|
|
|
|
|
|
|
|
|
|
|
if (numCurves < 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
return allOverlaps;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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::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<Overlap> SolutionToOverlap(Clipper2Lib::PathsD& solution, const std::vector<CCurveEx*>& curves, CCurveEx* pFirst, CCurveEx* pSecond) const
|
|
|
|
|
|
{
|
|
|
|
|
|
std::vector<Overlap> result;
|
|
|
|
|
|
|
|
|
|
|
|
for (const auto& solutionPath : solution)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<CCurveEx> 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;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|