| 70 | } |
| 71 | |
| 72 | std::vector<double> LNLib::KnotVectorUtils::GetInsertedKnotElement( |
| 73 | int degree, |
| 74 | const std::vector<double>& knotVector, |
| 75 | double startParam, |
| 76 | double endParam) |
| 77 | { |
| 78 | VALIDATE_ARGUMENT(degree >= 0, "degree", "Degree must be >= 0."); |
| 79 | VALIDATE_ARGUMENT(!knotVector.empty(), "knotVector", "KnotVector must not be empty."); |
| 80 | VALIDATE_ARGUMENT(startParam <= endParam, "startParam/endParam", "startParam must <= endParam."); |
| 81 | VALIDATE_ARGUMENT(ValidationUtils::IsValidKnotVector(knotVector), "knotVector", "Must be non-decreasing."); |
| 82 | |
| 83 | std::vector<double> result; |
| 84 | |
| 85 | int startMulti = 0; |
| 86 | for (double k : knotVector) { |
| 87 | if (MathUtils::IsAlmostEqualTo(k, startParam)) { |
| 88 | ++startMulti; |
| 89 | } |
| 90 | else { |
| 91 | break; |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | if (startMulti < degree + 1) { |
| 96 | int need = (degree + 1) - startMulti; |
| 97 | for (int i = 0; i < need; ++i) { |
| 98 | result.push_back(startParam); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | int endMulti = 0; |
| 103 | for (auto it = knotVector.rbegin(); it != knotVector.rend(); ++it) { |
| 104 | if (MathUtils::IsAlmostEqualTo(*it, endParam)) { |
| 105 | ++endMulti; |
| 106 | } |
| 107 | else { |
| 108 | break; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | if (endMulti < degree + 1) { |
| 113 | int need = (degree + 1) - endMulti; |
| 114 | for (int i = 0; i < need; ++i) { |
| 115 | result.push_back(endParam); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | return result; |
| 120 | } |
| 121 | |
| 122 | std::map<double, int> LNLib::KnotVectorUtils::GetKnotMultiplicityMap(const std::vector<double>& knotVector) |
| 123 | { |
nothing calls this directly
no outgoing calls
no test coverage detected