Skip to content

Commit 7437cb0

Browse files
committed
Fix BSpline normalization error #45
1 parent 813f256 commit 7437cb0

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

src/Spline.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -284,15 +284,19 @@ namespace dxfv
284284

285285
void CSpline::BSplineInit()
286286
{
287+
// check that there are some knots
287288
if (!vknots.size())
288289
return;
289290

290-
if (fabs(1 - vknots.back()) > 0.01)
291-
{
292-
// normalize knot values
293-
for (double &v : vknots)
294-
v /= vknots.back();
295-
}
291+
// normalize the knots to the range 0 to 1 inclusive
292+
double min = vknots[0];
293+
double max = vknots.back();
294+
if (max <= min)
295+
throw std::runtime_error("BSpline has invalid knot values");
296+
double scale = max - min;
297+
double off = min;
298+
for (auto &t : vknots)
299+
t = (t - off) / scale;
296300
}
297301

298302
cP operator*(double s, cP b)
@@ -516,10 +520,9 @@ namespace dxfv
516520
std::vector<double> d;
517521
for (int j1 = 0; j1 < myDegree + 1; j1++)
518522
{
519-
// quick fix: clamp index to >= 0 TID45 https://github.com/JamesBremner/DXF_Viewer/issues/45#issuecomment-2561315430
520523
int index = j1 + k - myDegree;
521-
if( index < 0 )
522-
index = 0;
524+
if (index < 0)
525+
throw std::runtime_error("CSpline::deBoor bad knot index");
523526

524527
d.push_back(c[index]);
525528
}
@@ -528,9 +531,9 @@ namespace dxfv
528531
for (int j = myDegree; j > r - 1; j--)
529532
{
530533
double div = vknots[j + 1 + k - r] - vknots[j + k - myDegree];
531-
double alpha = 0.5; // this is a guess to prevent nan TID45
532-
if (fabs(div) > 0.00001)
533-
alpha = (x - vknots[j + k - myDegree]) / div;
534+
if (div < 0.0000001)
535+
throw std::runtime_error("CSpline::deBoor divide by zero");
536+
double alpha = (x - vknots[j + k - myDegree]) / div;
534537
d[j] = (1 - alpha) * d[j - 1] + alpha * d[j];
535538
}
536539
}

0 commit comments

Comments
 (0)