|
|
|
|
|
#include "StdAfx.h"
|
|
|
|
|
|
#include "SplineAlgorithm.h"
|
|
|
|
|
|
#include <cfloat>
|
|
|
|
|
|
|
|
|
|
|
|
int SplineAlgorithm::FindClosestPointIndex(const dfPoint& point, const CCurveEx* pCurve)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pCurve == nullptr)
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
int closestIndex = -1;
|
|
|
|
|
|
double minDistSq = DBL_MAX;
|
|
|
|
|
|
for (int j = 0; j < pCurve->num; ++j)
|
|
|
|
|
|
{
|
|
|
|
|
|
double dx = point.x0 - pCurve->x[j];
|
|
|
|
|
|
double dy = point.y0 - pCurve->y[j];
|
|
|
|
|
|
double distSq = dx * dx + dy * dy;
|
|
|
|
|
|
if (distSq < minDistSq)
|
|
|
|
|
|
{
|
|
|
|
|
|
minDistSq = distSq;
|
|
|
|
|
|
closestIndex = j;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return closestIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<int> SplineAlgorithm::FindClosestPointIndices(const std::vector<dfPoint>& points, const CCurveEx* pCurve)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::vector<int> indices;
|
|
|
|
|
|
if (pCurve == nullptr)
|
|
|
|
|
|
return indices;
|
|
|
|
|
|
indices.reserve(points.size());
|
|
|
|
|
|
for (const auto& pt : points)
|
|
|
|
|
|
indices.push_back(FindClosestPointIndex(pt, pCurve));
|
|
|
|
|
|
return indices;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SplineAlgorithm::SimplifyCurve(CCurveEx& input, double errorThreshold, int oldHandleCount, CCurveEx& output)
|
|
|
|
|
|
{
|
|
|
|
|
|
CCurveRedundant redundant;
|
|
|
|
|
|
redundant.SetCurve(input);
|
|
|
|
|
|
double baseErr = errorThreshold;
|
|
|
|
|
|
bool isFirstGeneration = (oldHandleCount == 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (isFirstGeneration)
|
|
|
|
|
|
{
|
|
|
|
|
|
redundant.Execute(baseErr);
|
|
|
|
|
|
redundant.GetRedundantCurve(output);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
redundant.Execute(baseErr);
|
|
|
|
|
|
CCurveEx tempCurve;
|
|
|
|
|
|
redundant.GetRedundantCurve(tempCurve);
|
|
|
|
|
|
const double maxGrowthRatio = 1.2;
|
|
|
|
|
|
bool isTooManyHandles = (tempCurve.num > oldHandleCount * maxGrowthRatio);
|
|
|
|
|
|
|
|
|
|
|
|
if (isTooManyHandles)
|
|
|
|
|
|
{
|
|
|
|
|
|
double actualGrowthRatio = (double)tempCurve.num / oldHandleCount;
|
|
|
|
|
|
double adjustedErr = baseErr * actualGrowthRatio;
|
|
|
|
|
|
redundant.Execute(adjustedErr);
|
|
|
|
|
|
redundant.GetRedundantCurve(output);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
output = tempCurve;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|