Generic interpolation dispatcher.
390{
391 switch (mode) {
392 case InterpolationMode::LINEAR:
393 if (control_points.cols() < 2) {
394 error<std::invalid_argument>(
395 Journal::Component::Kinesis,
396 Journal::Context::Runtime,
397 std::source_location::current(),
398 "Linear interpolation requires at least 2 points, but got {}",
399 control_points.cols());
400 }
401 return (1.0 - t) * control_points.col(0) + t * control_points.col(1);
402
403 case InterpolationMode::CATMULL_ROM:
404 return catmull_rom_spline(control_points, t, tension);
405
406 case InterpolationMode::CUBIC_HERMITE: {
407 Eigen::MatrixXd endpoints = control_points.leftCols(2);
408 Eigen::MatrixXd tangents = control_points.rightCols(2);
409 return cubic_hermite(endpoints, tangents, t);
410 }
411
412 case InterpolationMode::CUBIC_BEZIER:
413 return cubic_bezier(control_points, t);
414
415 case InterpolationMode::QUADRATIC_BEZIER:
416 return quadratic_bezier(control_points, t);
417
418 case InterpolationMode::BSPLINE:
419 return bspline_cubic(control_points, t);
420
421 case InterpolationMode::COSINE: {
422 if (control_points.cols() < 2) {
423 error<std::invalid_argument>(
424 Journal::Component::Kinesis,
425 Journal::Context::Runtime,
426 std::source_location::current(),
427 "Cosine interpolation requires at least 2 points, but got {}",
428 control_points.cols());
429 }
430 double mu2 = (1.0 - std::cos(t * M_PI)) * 0.5;
431 return (1.0 - mu2) * control_points.col(0) + mu2 * control_points.col(1);
432 }
433
434 default:
435 error<std::invalid_argument>(
436 Journal::Component::Kinesis,
437 Journal::Context::Runtime,
438 std::source_location::current(),
439 "Unsupported interpolation mode: {}",
440 static_cast<int>(mode));
441 }
442}