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.
kev/Drawer/Module/GeoSigmaDraw/SplineAlgorithm.cpp

69 lines
1.7 KiB
C++

1 month ago
#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;
}
}
}