243 const int intervals = a.size() - 1;
256 const T c = (a.last().y() - a.first().y()) / (a.last().x() - a.first().x());
257 const T d = a.first().y() - c * a.first().x();
262 using Triplet = Eigen::Triplet<qreal>;
263 using Matrix = Eigen::SparseMatrix<qreal>;
264 using Vector = Eigen::VectorXd;
266 const int numberOfRows = intervals * 4;
267 const int numberOfColumns = numberOfRows;
268 std::vector<Triplet> triplets;
269 Matrix
A(numberOfRows, numberOfColumns);
270 Vector b(numberOfRows);
273 triplets.reserve(numberOfRows * 4);
279 T pointX = a.first().x();
280 T pointY = a.first().y();
281 T pointXSquared = pointX * pointX;
282 T pointXCubed = pointXSquared * pointX;
283 for (qint32 i = 0; i < intervals; ++i) {
284 const int baseColumn = i * 4;
286 triplets.push_back(Triplet(row, baseColumn + 0, pointXCubed));
287 triplets.push_back(Triplet(row, baseColumn + 1, pointXSquared));
288 triplets.push_back(Triplet(row, baseColumn + 2, pointX));
289 triplets.push_back(Triplet(row, baseColumn + 3, 1.0));
294 pointX = a[i + 1].x();
295 pointY = a[i + 1].y();
296 pointXSquared = pointX * pointX;
297 pointXCubed = pointXSquared * pointX;
298 triplets.push_back(Triplet(row, baseColumn + 0, pointXCubed));
299 triplets.push_back(Triplet(row, baseColumn + 1, pointXSquared));
300 triplets.push_back(Triplet(row, baseColumn + 2, pointX));
301 triplets.push_back(Triplet(row, baseColumn + 3, 1.0));
307 pointX = a.first().x();
308 triplets.push_back(Triplet(row, 0, 6.0 * pointX));
309 triplets.push_back(Triplet(row, 1, 2.0));
312 pointX = a.last().x();
313 triplets.push_back(Triplet(row, numberOfColumns - 4, 6.0 * pointX));
314 triplets.push_back(Triplet(row, numberOfColumns - 3, 2.0));
318 for (qint32 i = 1; i < a.size() - 1; ++i) {
320 const qint32 baseColumn = i * 4;
321 if (a[i].isSetAsCorner()) {
322 triplets.push_back(Triplet(row, baseColumn - 4, 6.0 * pointX));
323 triplets.push_back(Triplet(row, baseColumn - 3, 2.0));
326 triplets.push_back(Triplet(row, baseColumn + 0, 6.0 * pointX));
327 triplets.push_back(Triplet(row, baseColumn + 1, 2.0));
331 pointXSquared = pointX * pointX;
333 triplets.push_back(Triplet(row, baseColumn - 4, 3.0 * pointXSquared));
334 triplets.push_back(Triplet(row, baseColumn - 3, 2.0 * pointX));
335 triplets.push_back(Triplet(row, baseColumn - 2, 1.0));
336 triplets.push_back(Triplet(row, baseColumn + 0, -3.0 * pointXSquared));
337 triplets.push_back(Triplet(row, baseColumn + 1, -2.0 * pointX));
338 triplets.push_back(Triplet(row, baseColumn + 2, -1.0));
342 triplets.push_back(Triplet(row, baseColumn - 4, 6.0 * pointX));
343 triplets.push_back(Triplet(row, baseColumn - 3, 2.0));
344 triplets.push_back(Triplet(row, baseColumn + 0, -6.0 * pointX));
345 triplets.push_back(Triplet(row, baseColumn + 1, -2.0));
351 A.setFromTriplets(triplets.begin(), triplets.end());
352 Eigen::SparseLU<Matrix> solver(
A);
353 Vector x = solver.solve(b);
355 for (qint32 i = 0; i < intervals; ++i) {
357 m_coefficients.append({x(row), x(row + 1), x(row + 2), x(row + 3)});