MCPcopy Create free account
hub / github.com/BIMCoderLiang/LNLib / OneBasisFunction

Method OneBasisFunction

src/LNLib/Algorithm/Polynomials.cpp:399–455  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

397}
398
399double LNLib::Polynomials::OneBasisFunction(int spanIndex, int degree, const std::vector<double>& knotVector, double paramT)
400{
401 VALIDATE_ARGUMENT(spanIndex >= 0, "spanIndex", "SpanIndex must be greater than or equal zero.");
402 VALIDATE_ARGUMENT(degree > 0, "degree", "Degree must be greater than zero.");
403 VALIDATE_ARGUMENT(knotVector.size() > 0, "knotVector", "KnotVector size must be greater than zero.");
404 VALIDATE_ARGUMENT(ValidationUtils::IsValidKnotVector(knotVector), "knotVector", "KnotVector must be a nondecreasing sequence of real numbers.");
405 VALIDATE_ARGUMENT_RANGE(paramT, knotVector[0], knotVector[knotVector.size() - 1]);
406
407 int m = knotVector.size() - 1;
408 if ((spanIndex == 0 && MathUtils::IsAlmostEqualTo(paramT, knotVector[0])) ||
409 (spanIndex == m - degree - 1 && MathUtils::IsAlmostEqualTo(paramT, knotVector[m])))
410 {
411 return 1.0;
412 }
413 if (MathUtils::IsLessThan(paramT, knotVector[spanIndex]) ||
414 MathUtils::IsGreaterThanOrEqual(paramT, knotVector[spanIndex + degree + 1]))
415 {
416 return 0.0;
417 }
418
419 std::vector<double> N(degree + spanIndex + 1, 0.0);
420 for (int j = 0; j <= degree; j++)
421 {
422 if (MathUtils::IsGreaterThanOrEqual(paramT, knotVector[spanIndex + j]) &&
423 MathUtils::IsLessThan(paramT, knotVector[spanIndex + j + 1]))
424 {
425 N[j] = 1.0;
426 }
427 }
428
429 for (int k = 1; k <= degree; k++)
430 {
431 double saved = 0.0;
432 if (!MathUtils::IsAlmostEqualTo(N[0], 0.0))
433 {
434 saved = ((paramT - knotVector[spanIndex]) * N[0]) / (knotVector[spanIndex + k] - knotVector[spanIndex]);
435 }
436
437 for (int j = 0; j < degree - k + 1; j++)
438 {
439 double knotLeft = knotVector[spanIndex + j + 1];
440 double knotRight = knotVector[spanIndex + j + k + 1];
441 if (MathUtils::IsAlmostEqualTo(N[j + 1], 0.0))
442 {
443 N[j] = saved;
444 saved = 0.0;
445 }
446 else
447 {
448 double temp = N[j + 1] / (knotRight - knotLeft);
449 N[j] = saved + (knotRight - paramT) * temp;
450 saved = (paramT - knotLeft) * temp;
451 }
452 }
453 }
454 return N[0];
455}
456

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected