2021-09-13 15:53:43 +03:00
|
|
|
//
|
|
|
|
// Created by Иван Ильин on 26.01.2021.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef ENGINE_INTERPOLATION_H
|
|
|
|
#define ENGINE_INTERPOLATION_H
|
|
|
|
|
|
|
|
#include <cmath>
|
2021-10-31 11:39:08 +03:00
|
|
|
|
|
|
|
#include "../Vec2D.h"
|
2021-10-09 13:41:12 +03:00
|
|
|
#include "../Consts.h"
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
namespace Interpolation {
|
|
|
|
static double Linear(double t);
|
2021-10-31 11:39:08 +03:00
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
static double Cos(double t);
|
2021-10-31 11:39:08 +03:00
|
|
|
|
|
|
|
static double Bezier(const Vec2D &p1, const Vec2D &p2, double t);
|
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
static double Bouncing(double t);
|
|
|
|
|
|
|
|
static double dLinear(double t, double dt);
|
2021-10-31 11:39:08 +03:00
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
static double dCos(double t, double dt);
|
2021-10-31 11:39:08 +03:00
|
|
|
|
|
|
|
static double dBezier(const Vec2D &p1, const Vec2D &p2, double t, double dt);
|
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
static double dBouncing(double t, double dt);
|
|
|
|
};
|
|
|
|
|
|
|
|
double Interpolation::Linear(double t) {
|
2021-11-01 17:48:26 +03:00
|
|
|
if (t < 0) {
|
2021-09-13 15:53:43 +03:00
|
|
|
t = -t;
|
2021-11-01 17:48:26 +03:00
|
|
|
}
|
|
|
|
int integer = static_cast<int>(t);
|
|
|
|
|
|
|
|
return (integer % 2) ? 1.0 - (t - integer) : (t - integer);
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
double Interpolation::Cos(double t) {
|
2021-10-31 11:39:08 +03:00
|
|
|
return 0.5 * (1 - cos(Consts::PI * Interpolation::Linear(t)));
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-12 17:12:47 +03:00
|
|
|
double Interpolation::Bezier(const Vec2D &p1, const Vec2D &p2, double t) {
|
2021-10-30 12:24:19 +03:00
|
|
|
// TODO: implement bezier curve without finding the root of equation
|
2021-09-13 15:53:43 +03:00
|
|
|
t = Interpolation::Linear(t);
|
|
|
|
|
2021-10-12 17:12:47 +03:00
|
|
|
double h = Consts::EPS;
|
|
|
|
double eps = Consts::EPS;
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
// We are trying to find 's' when px = t
|
2021-10-31 11:39:08 +03:00
|
|
|
auto f = [=](double s) {
|
|
|
|
return 3.0 * (1.0 - s) * (1.0 - s) * s * p1.x() + 3.0 * (1.0 - s) * s * s * p2.x() + s * s * s - t;
|
2021-09-13 15:53:43 +03:00
|
|
|
};
|
|
|
|
// Using found 's' we will calculate resulting py
|
2021-10-31 11:39:08 +03:00
|
|
|
auto py = [=](double s) {
|
|
|
|
return 3.0 * (1.0 - s) * (1.0 - s) * s * p1.y() + 3.0 * (1.0 - s) * s * s * p2.y() + s * s * s;
|
2021-09-13 15:53:43 +03:00
|
|
|
};
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
auto df = [=](double s) {
|
|
|
|
return (f(s + h) - f(s - h)) / (2.0 * h);
|
2021-09-13 15:53:43 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
// Newton method
|
|
|
|
double s1 = 0.0, s2 = 0.5;
|
|
|
|
int i = 0;
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
while (std::abs(s1 - s2) > eps) {
|
2021-09-13 15:53:43 +03:00
|
|
|
s1 = s2;
|
|
|
|
s2 = s1 - f(s1) / df(s1);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return py(s1);
|
|
|
|
}
|
|
|
|
|
|
|
|
double Interpolation::Bouncing(double t) {
|
|
|
|
t = Interpolation::Linear(t);
|
2021-10-31 11:39:08 +03:00
|
|
|
return 0.5 * (1.0 / (1.0 + exp(10.0 * (-4.0 * t + 0.8))) +
|
|
|
|
(1.0 + 2.5 * sin(50.0 * (t - 1.0 / 3.0)) * exp(-7.0 * t)) / (1.0 + exp(10.0 * (-15.0 * t + 3.1))));
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
double Interpolation::dLinear(double t, double dt) {
|
2021-10-31 11:39:08 +03:00
|
|
|
return ((int) trunc(t) % 2) ? -dt : dt;
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
double Interpolation::dCos(double t, double dt) {
|
2021-10-31 11:39:08 +03:00
|
|
|
return 0.5 * Consts::PI * sin(Consts::PI * t) * dt;
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-12 17:12:47 +03:00
|
|
|
double Interpolation::dBezier(const Vec2D &p1, const Vec2D &p2, double t, double dt) {
|
2021-09-13 15:53:43 +03:00
|
|
|
return Interpolation::Bezier(p1, p2, t + dt) - Interpolation::Bezier(p1, p2, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
double Interpolation::dBouncing(double t, double dt) {
|
|
|
|
return Bouncing(t + dt) - Bouncing(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif //INC_3DZAVR_INTERPOLATION_H
|