| 193 | } |
| 194 | |
| 195 | std::vector<std::vector<double>> LNLib::Polynomials::BasisFunctionsDerivatives(int spanIndex, int degree, |
| 196 | int derivative, const std::vector<double>& knotVector, double paramT) |
| 197 | { |
| 198 | VALIDATE_ARGUMENT(spanIndex >= 0, "spanIndex", "SpanIndex must be greater than or equal zero."); |
| 199 | VALIDATE_ARGUMENT(degree >= 0 && degree <= Constants::NURBSMaxDegree, "degree", "Degree must be greater than or equal zero and not exceed the maximun degree."); |
| 200 | VALIDATE_ARGUMENT(derivative <= degree, "derivative", "Derivative must not be greater than degree."); |
| 201 | VALIDATE_ARGUMENT(knotVector.size() > 0, "knotVector", "KnotVector size must be greater than zero."); |
| 202 | VALIDATE_ARGUMENT(ValidationUtils::IsValidKnotVector(knotVector), "knotVector", "KnotVector must be a nondecreasing sequence of real numbers."); |
| 203 | VALIDATE_ARGUMENT_RANGE(paramT, knotVector[0], knotVector[knotVector.size() - 1]); |
| 204 | |
| 205 | std::vector<std::vector<double>> derivatives(derivative + 1, std::vector<double>(degree + 1)); |
| 206 | std::vector<std::vector<double>> ndu(degree + 1,std::vector<double>(degree + 1)); |
| 207 | |
| 208 | ndu[0][0] = 1.0; |
| 209 | |
| 210 | double left[Constants::NURBSMaxDegree + 1]; |
| 211 | double right[Constants::NURBSMaxDegree + 1]; |
| 212 | |
| 213 | double saved = 0.0; |
| 214 | double temp = 0.0; |
| 215 | |
| 216 | for (int j = 1; j <= degree; j++) |
| 217 | { |
| 218 | left[j] = paramT - knotVector[spanIndex + 1 - j]; |
| 219 | right[j] = knotVector[spanIndex + j] - paramT; |
| 220 | |
| 221 | saved = 0.0; |
| 222 | for (int r = 0; r < j; r++) |
| 223 | { |
| 224 | ndu[j][r] = right[r + 1] + left[j - r]; |
| 225 | temp = ndu[r][j - 1] / ndu[j][r]; |
| 226 | |
| 227 | ndu[r][j] = saved + right[r + 1] * temp; |
| 228 | saved = left[j - r] * temp; |
| 229 | } |
| 230 | ndu[j][j] = saved; |
| 231 | } |
| 232 | |
| 233 | for (int j = 0; j <= degree; j++) |
| 234 | { |
| 235 | derivatives[0][j] = ndu[j][degree]; |
| 236 | } |
| 237 | |
| 238 | std::vector<std::vector<double>> a(2,std::vector<double>(degree + 1)); |
| 239 | for (int r = 0; r <= degree; r++) |
| 240 | { |
| 241 | int s1 = 0; |
| 242 | int s2 = 1; |
| 243 | a[0][0] = 1.0; |
| 244 | |
| 245 | for (int k = 1; k <= derivative; k++) |
| 246 | { |
| 247 | double d = 0.0; |
| 248 | int rk = r - k; |
| 249 | int pk = degree - k; |
| 250 | |
| 251 | if (r >= k) |
| 252 | { |
nothing calls this directly
no outgoing calls
no test coverage detected