240 {
242
243 const int intervals = a.size() - 1;
245
247
248 if (a.size() == 1) {
249
251 return;
252 }
253
254 if (a.size() == 2) {
255
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();
259 return;
260 }
261
262 using Triplet = Eigen::Triplet<qreal>;
263 using Matrix = Eigen::SparseMatrix<qreal>;
264 using Vector = Eigen::VectorXd;
265
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);
271
272
273 triplets.reserve(numberOfRows * 4);
274 qint32 row = 0;
275
276
277
278
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;
285
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));
291 ++row;
292
293
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));
303 ++row;
304 }
305
306
307 pointX = a.first().x();
308 triplets.push_back(Triplet(row, 0, 6.0 * pointX));
309 triplets.push_back(Triplet(row, 1, 2.0));
311 ++row;
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));
316 ++row;
317
318 for (qint32 i = 1; i < a.size() - 1; ++i) {
319 pointX = a[i].x();
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));
325 ++row;
326 triplets.push_back(Triplet(row, baseColumn + 0, 6.0 * pointX));
327 triplets.push_back(Triplet(row, baseColumn + 1, 2.0));
329 ++row;
330 } else {
331 pointXSquared = pointX * pointX;
332
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));
340 ++row;
341
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));
347 ++row;
348 }
349 }
350
351 A.setFromTriplets(triplets.begin(), triplets.end());
352 Eigen::SparseLU<Matrix> solver(
A);
353 Vector
x = solver.solve(b);
354
355 for (qint32 i = 0; i < intervals; ++i) {
356 row = i * 4;
358 }
359 }
QList< T_point > m_points
QList< Coefficients > m_coefficients
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)