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

Method OneBasisFunctionDerivative

src/LNLib/Algorithm/Polynomials.cpp:457–544  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

455}
456
457std::vector<double> LNLib::Polynomials::OneBasisFunctionDerivative(int spanIndex, int degree, int derivative, const std::vector<double>& knotVector, double paramT)
458{
459 VALIDATE_ARGUMENT(spanIndex >= 0, "spanIndex", "SpanIndex must be greater than or equal zero.");
460 VALIDATE_ARGUMENT(degree > 0, "degree", "Degree must be greater than zero.");
461 VALIDATE_ARGUMENT(derivative <= degree, "derivative", "Derivative must not be greater than degree.");
462 VALIDATE_ARGUMENT(knotVector.size() > 0, "knotVector", "KnotVector size must be greater than zero.");
463 VALIDATE_ARGUMENT(ValidationUtils::IsValidKnotVector(knotVector), "knotVector", "KnotVector must be a nondecreasing sequence of real numbers.");
464 VALIDATE_ARGUMENT_RANGE(paramT, knotVector[0], knotVector[knotVector.size() - 1]);
465
466 std::vector<double> derivatives(derivative + 1, 0.0);
467
468 if (MathUtils::IsLessThan(paramT, knotVector[spanIndex]) ||
469 MathUtils::IsGreaterThanOrEqual(paramT, knotVector[spanIndex + degree + 1]))
470 {
471 return derivatives;
472 }
473
474 std::vector<std::vector<double>> N(degree + 1, std::vector<double>(degree + 1,0.0));
475
476 for (int j = 0; j <= degree; j++)
477 {
478 if (MathUtils::IsGreaterThanOrEqual(paramT, knotVector[spanIndex + j]) &&
479 MathUtils::IsLessThan(paramT, knotVector[spanIndex + j + 1]))
480 {
481 N[j][0] = 1.0;
482 }
483 }
484 for (int k = 1; k <= degree; k++)
485 {
486 double saved = 0.0;
487 if (!MathUtils::IsAlmostEqualTo(N[0][k - 1], 0.0))
488 {
489 saved = ((paramT - knotVector[spanIndex]) * N[0][k - 1]) / (knotVector[spanIndex + k] - knotVector[spanIndex]);
490 }
491 for (int j = 0; j < degree - k + 1; j++)
492 {
493 double knotLeft = knotVector[spanIndex + j + 1];
494 double knotRight = knotVector[spanIndex + j + k + 1];
495
496 if (MathUtils::IsAlmostEqualTo(N[j + 1][k - 1], 0.0))
497 {
498 N[j][k] = saved;
499 saved = 0.0;
500 }
501 else
502 {
503 double temp = N[j + 1][k - 1] / (knotRight - knotLeft);
504 N[j][k] = saved + (knotRight - paramT) * temp;
505 saved = (paramT - knotLeft) * temp;
506 }
507 }
508 }
509
510 derivatives[0] = N[0][degree];
511
512 for (int k = 1; k <= derivative; k++)
513 {
514 std::vector<double> ND(k+1,0.0);

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected