Path: Adaptive - small performance improvement
- related to linking path smoothing
This commit is contained in:
@@ -44,15 +44,15 @@ using namespace std;
|
||||
|
||||
inline double DistanceSqrd(const IntPoint &pt1, const IntPoint &pt2)
|
||||
{
|
||||
double Dx = ((double)pt1.X - pt2.X);
|
||||
double dy = ((double)pt1.Y - pt2.Y);
|
||||
double Dx = double(pt1.X - pt2.X);
|
||||
double dy = double(pt1.Y - pt2.Y);
|
||||
return (Dx * Dx + dy * dy);
|
||||
}
|
||||
|
||||
inline bool SetSegmentLength(const IntPoint &pt1, IntPoint &pt2, double new_length)
|
||||
{
|
||||
double Dx = ((double)pt2.X - pt1.X);
|
||||
double dy = ((double)pt2.Y - pt1.Y);
|
||||
double Dx = double(pt2.X - pt1.X);
|
||||
double dy = double(pt2.Y - pt1.Y);
|
||||
double l = sqrt(Dx * Dx + dy * dy);
|
||||
if (l > 0.0)
|
||||
{
|
||||
@@ -119,8 +119,8 @@ inline double Angle3Points(const DoublePoint &p1, const DoublePoint &p2, const D
|
||||
|
||||
inline DoublePoint DirectionV(const IntPoint &pt1, const IntPoint &pt2)
|
||||
{
|
||||
double DX = pt2.X - pt1.X;
|
||||
double DY = pt2.Y - pt1.Y;
|
||||
double DX = double(pt2.X - pt1.X);
|
||||
double DY = double(pt2.Y - pt1.Y);
|
||||
double l = sqrt(DX * DX + DY * DY);
|
||||
if (l < NTOL)
|
||||
return DoublePoint(0, 0);
|
||||
@@ -316,11 +316,20 @@ double DistancePointToLineSegSquared(const IntPoint &p1, const IntPoint &p2, con
|
||||
return DX * DX + DY * DY; // return distance squared
|
||||
}
|
||||
|
||||
void ScalePaths(Paths &paths,double scaleFactor) {
|
||||
void ScaleUpPaths(Paths &paths,long scaleFactor) {
|
||||
for(auto &pth:paths) {
|
||||
for(auto &pt:pth) {
|
||||
pt.X= pt.X * scaleFactor;
|
||||
pt.Y= pt.Y * scaleFactor;
|
||||
pt.X*=scaleFactor;
|
||||
pt.Y*=scaleFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScaleDownPaths(Paths &paths,long scaleFactor) {
|
||||
for(auto &pth:paths) {
|
||||
for(auto &pt:pth) {
|
||||
pt.X/=scaleFactor;
|
||||
pt.Y/=scaleFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,41 +582,49 @@ bool IntersectionPoint(const Paths &paths, const IntPoint &p1, const IntPoint &p
|
||||
void SmoothPaths(Paths &paths, double stepSize, long pointCount, long iterations)
|
||||
{
|
||||
Paths output;
|
||||
output.clear();
|
||||
output.resize(paths.size());
|
||||
double scale=1000;
|
||||
ScalePaths(paths,scale);
|
||||
const long scale=1000;
|
||||
const double stepScaled = stepSize*scale;
|
||||
|
||||
ScaleUpPaths(paths,scale);
|
||||
vector<pair<size_t /*path index*/, IntPoint>> points;
|
||||
for (size_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
for (auto &pt : paths[i])
|
||||
for (const auto &pt : paths[i])
|
||||
{
|
||||
if (points.empty())
|
||||
{
|
||||
points.push_back(pair<size_t /*path index*/, IntPoint>(i, pt));
|
||||
continue;
|
||||
}
|
||||
IntPoint lastPt = points.back().second;
|
||||
size_t lastPathIndex = points.back().first;
|
||||
const auto &back=points.back();
|
||||
const IntPoint & lastPt = back.second;
|
||||
|
||||
double l = sqrt(DistanceSqrd(lastPt, pt));
|
||||
|
||||
if (l < 0.5*stepSize*scale)
|
||||
const double l = sqrt(DistanceSqrd(lastPt, pt));
|
||||
|
||||
if (l < 0.5*stepScaled)
|
||||
{
|
||||
points.pop_back();
|
||||
points.push_back(pair<size_t /*path index*/, IntPoint>(i, pt));
|
||||
continue;
|
||||
}
|
||||
|
||||
long steps = long(l / (stepSize*scale))+1; // +1 is important!
|
||||
size_t lastPathIndex = back.first;
|
||||
const long steps = long(l / stepScaled)+1; // +1 is important!
|
||||
const long left=pointCount*2;
|
||||
const long right =steps-pointCount*2;
|
||||
for (long idx = 0; idx <= steps; idx++)
|
||||
{
|
||||
double p = double(idx) / steps;
|
||||
IntPoint ptx(long(lastPt.X + double(pt.X - lastPt.X) * p),
|
||||
long(lastPt.Y + double(pt.Y - lastPt.Y) * p));
|
||||
if(idx==0) {
|
||||
if(DistanceSqrd(points.back().second,ptx)<scale) points.pop_back();
|
||||
if(idx>left && idx<right) {
|
||||
idx=right;
|
||||
continue;
|
||||
}
|
||||
const double p = double(idx) / steps;
|
||||
const IntPoint ptx(long(lastPt.X + double(pt.X - lastPt.X) * p),
|
||||
long(lastPt.Y + double(pt.Y - lastPt.Y) * p));
|
||||
|
||||
if(idx==0 && DistanceSqrd(back.second,ptx)<scale) points.pop_back();
|
||||
|
||||
if (p < 0.5)
|
||||
points.push_back(pair<size_t /*path index*/, IntPoint>(lastPathIndex, ptx));
|
||||
else
|
||||
@@ -617,48 +634,49 @@ void SmoothPaths(Paths &paths, double stepSize, long pointCount, long iterations
|
||||
}
|
||||
if (points.empty())
|
||||
return;
|
||||
long size=long(points.size());
|
||||
const long size=long(points.size());
|
||||
double rangeSqrd = stepScaled * 2 * pointCount; rangeSqrd*=rangeSqrd;
|
||||
for(long iter=0;iter<iterations; iter++) {
|
||||
for (long i = 0; i < size; i++)
|
||||
{
|
||||
IntPoint avgPoint(points[i].second);
|
||||
double cnt = 1;
|
||||
IntPoint &cp = points[i].second;
|
||||
IntPoint avgPoint(cp);
|
||||
long cnt = 1;
|
||||
|
||||
long ptsToAverage = pointCount;
|
||||
if (i < ptsToAverage)
|
||||
ptsToAverage = max(i-1,0L);
|
||||
while (i + ptsToAverage >= long(points.size()-1))
|
||||
ptsToAverage--;
|
||||
else if(i + ptsToAverage >= size-1)
|
||||
ptsToAverage = size-1-i;
|
||||
|
||||
for (long j = i-ptsToAverage; j <= i+ptsToAverage; j++)
|
||||
{
|
||||
if (j != i)
|
||||
{
|
||||
long index=j;
|
||||
if(index<0) index=0;
|
||||
if(index>=size) index=size-1;
|
||||
IntPoint &p = points.at(index).second;
|
||||
if (j == i) continue;
|
||||
long index=j;
|
||||
if(index<0) index=0;
|
||||
if(index>=size) index=size-1;
|
||||
IntPoint &p = points[index].second;
|
||||
if(DistanceSqrd(cp,p)<rangeSqrd) {
|
||||
avgPoint.X += p.X;
|
||||
avgPoint.Y += p.Y;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
avgPoint.X /= cnt;
|
||||
avgPoint.Y /= cnt;
|
||||
points[i].second=avgPoint;
|
||||
cp.X=avgPoint.X/cnt;
|
||||
cp.Y=avgPoint.Y/cnt;
|
||||
}
|
||||
}
|
||||
|
||||
for (long i = 0; i < size; i++)
|
||||
for (const auto &pr:points)
|
||||
{
|
||||
output.at(points[i].first).push_back(points[i].second);
|
||||
output[pr.first].push_back(pr.second);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
CleanPath(output[i], paths[i], scale);
|
||||
}
|
||||
ScalePaths(paths,1.0/scale);
|
||||
ScaleDownPaths(paths,scale);
|
||||
}
|
||||
|
||||
bool PopPathWithClosestPoint(Paths &paths /*closest path is removed from collection and shifted to start with closest point */
|
||||
@@ -2424,7 +2442,7 @@ void Adaptive2d::AppendToolPath(TPaths &progressPaths, AdaptiveOutput &output,
|
||||
|
||||
if (linkType == MotionType::mtLinkClear)
|
||||
{
|
||||
SmoothPaths(linkPaths, 0.05 * stepOverScaled,4,4);
|
||||
SmoothPaths(linkPaths, 0.05*stepOverScaled,4,2);
|
||||
}
|
||||
|
||||
leadOutPath = linkPaths[0];
|
||||
|
||||
Reference in New Issue
Block a user