MathUtils: Add exponential interpolation

Change-Id: I58bb26a6e921cbd1f5532bddcd6a6700ff80b94f
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Jarek Kobus
2022-11-28 11:28:49 +01:00
parent 23f53dcbda
commit 12b639970f
3 changed files with 50 additions and 5 deletions

View File

@@ -39,9 +39,26 @@ int interpolateTangential(int x, int xHalfLife, int y1, int y2)
return y1;
if (y1 == y2)
return y1;
const double mapped = atan2(double(x), double(xHalfLife));
const double progress = y1 + (y2 - y1) * mapped * 2 / M_PI;
return qRound(progress);
const double angle = atan2((double)x, (double)xHalfLife);
const double result = y1 + (y2 - y1) * angle * 2 / M_PI;
return qRound(result);
}
} // namespace Utils::Math
/*!
Exponential interpolation:
For x = 0 it returns y1.
For x = xHalfLife it returns 50 % of the distance between y1 and y2.
For x = infinity it returns y2.
*/
int interpolateExponential(int x, int xHalfLife, int y1, int y2)
{
if (x == 0)
return y1;
if (y1 == y2)
return y1;
const double exponent = pow(0.5, (double)x / xHalfLife);
const double result = y1 + (y2 - y1) * (1.0 - exponent);
return qRound(result);
}
} // namespace Utils::MathUtils

View File

@@ -9,5 +9,6 @@ namespace Utils::MathUtils {
QTCREATOR_UTILS_EXPORT int interpolateLinear(int x, int x1, int x2, int y1, int y2);
QTCREATOR_UTILS_EXPORT int interpolateTangential(int x, int xHalfLife, int y1, int y2);
QTCREATOR_UTILS_EXPORT int interpolateExponential(int x, int xHalfLife, int y1, int y2);
} // namespace Utils::Math
} // namespace Utils::MathUtils

View File

@@ -16,6 +16,8 @@ private slots:
void interpolateLinear();
void interpolateTangential_data();
void interpolateTangential();
void interpolateExponential_data();
void interpolateExponential();
};
void tst_MathUtils::interpolateLinear_data()
@@ -72,6 +74,31 @@ void tst_MathUtils::interpolateTangential()
QCOMPARE(y, result);
}
void tst_MathUtils::interpolateExponential_data()
{
QTest::addColumn<int>("x");
QTest::addColumn<int>("xHalfLife");
QTest::addColumn<int>("y1");
QTest::addColumn<int>("y2");
QTest::addColumn<int>("result");
QTest::newRow("zero") << 0 << 8 << 10 << 20 << 10;
QTest::newRow("halfLife") << 8 << 8 << 10 << 20 << 15;
QTest::newRow("approxInfinity") << 1000 << 8 << 10 << 20 << 20;
}
void tst_MathUtils::interpolateExponential()
{
QFETCH(int, x);
QFETCH(int, xHalfLife);
QFETCH(int, y1);
QFETCH(int, y2);
QFETCH(int, result);
const int y = MathUtils::interpolateExponential(x, xHalfLife, y1, y2);
QCOMPARE(y, result);
}
QTEST_GUILESS_MAIN(tst_MathUtils)
#include "tst_mathutils.moc"