@@ -284,15 +284,19 @@ namespace dxfv
284
284
285
285
void CSpline::BSplineInit ()
286
286
{
287
+ // check that there are some knots
287
288
if (!vknots.size ())
288
289
return ;
289
290
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;
296
300
}
297
301
298
302
cP operator *(double s, cP b)
@@ -516,10 +520,9 @@ namespace dxfv
516
520
std::vector<double > d;
517
521
for (int j1 = 0 ; j1 < myDegree + 1 ; j1++)
518
522
{
519
- // quick fix: clamp index to >= 0 TID45 https://github.com/JamesBremner/DXF_Viewer/issues/45#issuecomment-2561315430
520
523
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 " ) ;
523
526
524
527
d.push_back (c[index]);
525
528
}
@@ -528,9 +531,9 @@ namespace dxfv
528
531
for (int j = myDegree; j > r - 1 ; j--)
529
532
{
530
533
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;
534
537
d[j] = (1 - alpha) * d[j - 1 ] + alpha * d[j];
535
538
}
536
539
}
0 commit comments