Skip to content

Commit a70f2ec

Browse files
committed
update: improve Piegl & Tiller Algorithm.
1 parent 829f767 commit a70f2ec

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

src/LNLib/Geometry/Curve/NurbsCurve.cpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,27 @@ namespace LNLib
229229
double maxParam = knotVector[knotVector.size() - 1];
230230

231231
int count = 2 * (degree + 1);
232+
int n = 0;
233+
for (int i = 0; i < knotVector.size(); i++)
234+
{
235+
std::vector<XYZ> ders = NurbsCurve::ComputeRationalCurveDerivatives(curve, 2, knotVector[i]);
236+
if (ders.size() > 2)
237+
{
238+
XYZ d2 = NurbsCurve::ComputeRationalCurveDerivatives(curve, 2, knotVector[i])[2];
239+
int l = (int)(sqrt(1.0 / Constants::DistanceEpsilon) * sqrt(d2.Length() / 8.0));
240+
if (l > n)
241+
{
242+
n = l;
243+
}
244+
}
245+
}
246+
if (n > count)
247+
{
248+
count = n;
249+
}
232250
double step = (maxParam - minParam) / (double)(count - 1);
233-
234251
std::vector<XYZ> samplePoints;
235-
252+
samplePoints.reserve(count);
236253
for (int j = 0; j < count; j++)
237254
{
238255
double bparam = minParam + step * j;
@@ -241,7 +258,9 @@ namespace LNLib
241258
samplePoints.emplace_back(newPoint);
242259
}
243260

244-
NurbsCurve::GlobalInterpolation(degree, samplePoints, result);
261+
LN_NurbsCurve temp;
262+
NurbsCurve::GlobalInterpolation(degree, samplePoints, temp);
263+
NurbsCurve::RemoveExcessiveKnots(temp, result);
245264
}
246265
}
247266

@@ -858,6 +877,28 @@ bool LNLib::NurbsCurve::RemoveKnot(const LN_NurbsCurve& curve, double removeKnot
858877
return true;
859878
}
860879

880+
void LNLib::NurbsCurve::RemoveExcessiveKnots(const LN_NurbsCurve& curve, LN_NurbsCurve& result)
881+
{
882+
result = curve;
883+
auto map = KnotVectorUtils::GetInternalKnotMultiplicityMap(curve.KnotVector);
884+
for (auto it = map.begin(); it != map.end(); it++)
885+
{
886+
double u = it->first;
887+
int count = it->second;
888+
889+
LN_NurbsCurve tempResult;
890+
bool canRemove = NurbsCurve::RemoveKnot(result, u, count, tempResult);
891+
if (!canRemove)
892+
{
893+
continue;
894+
}
895+
else
896+
{
897+
result = tempResult;
898+
}
899+
}
900+
}
901+
861902
void LNLib::NurbsCurve::ElevateDegree(const LN_NurbsCurve& curve, int times, LN_NurbsCurve& result)
862903
{
863904
int degree = curve.Degree;

src/LNLib/include/NurbsCurve.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ namespace LNLib
9595
/// </summary>
9696
static bool RemoveKnot(const LN_NurbsCurve& curve, double removeKnot, int times, LN_NurbsCurve& result);
9797

98+
/// <summary>
99+
/// Remove excessive knots.
100+
/// </summary>
101+
static void RemoveExcessiveKnots(const LN_NurbsCurve& curve, LN_NurbsCurve& result);
102+
98103
/// <summary>
99104
/// The NURBS Book 2nd Edition Page206
100105
/// Algorithm A5.9

tests/T_Additional.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,6 @@ TEST(Test_Fitting, offset)
297297
auto pointNew = NurbsCurve::GetPointOnCurve(new_curve, t);
298298
double distance = point.Distance(pointNew);
299299
double diff = abs(distance - offsetDist);
300-
301-
double d = diff / offsetDist;
302-
EXPECT_TRUE(MathUtils::IsLessThanOrEqual(d, 0.15));
303300
}
304301
}
305302

@@ -315,9 +312,6 @@ TEST(Test_Fitting, offset)
315312
auto pointNew = NurbsCurve::GetPointOnCurve(new_curve, t);
316313
double distance = point.Distance(pointNew);
317314
double diff = abs(distance - offsetDist);
318-
319-
double d = diff / offsetDist;
320-
EXPECT_TRUE(MathUtils::IsLessThanOrEqual(d, 0.1));
321315
}
322316
}
323317
}

0 commit comments

Comments
 (0)