| 397 | } |
| 398 | |
| 399 | double 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 |
nothing calls this directly
no outgoing calls
no test coverage detected