diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2022-11-28 11:28:49 +0100 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2022-11-28 10:45:13 +0000 |
commit | 12b639970fc3ce08eada69d315470735fc23ef5f (patch) | |
tree | 9a8c162d2229fd8dfac9f10f11ed47446d047379 | |
parent | 23f53dcbda305d3e2f593b4e0c566375af7dc0fb (diff) |
MathUtils: Add exponential interpolation
Change-Id: I58bb26a6e921cbd1f5532bddcd6a6700ff80b94f
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r-- | src/libs/utils/mathutils.cpp | 25 | ||||
-rw-r--r-- | src/libs/utils/mathutils.h | 3 | ||||
-rw-r--r-- | tests/auto/utils/mathutils/tst_mathutils.cpp | 27 |
3 files changed, 50 insertions, 5 deletions
diff --git a/src/libs/utils/mathutils.cpp b/src/libs/utils/mathutils.cpp index d9e18b18a3..f1bdc5999c 100644 --- a/src/libs/utils/mathutils.cpp +++ b/src/libs/utils/mathutils.cpp @@ -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 diff --git a/src/libs/utils/mathutils.h b/src/libs/utils/mathutils.h index 8a9af9e4e6..21f66ff581 100644 --- a/src/libs/utils/mathutils.h +++ b/src/libs/utils/mathutils.h @@ -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 diff --git a/tests/auto/utils/mathutils/tst_mathutils.cpp b/tests/auto/utils/mathutils/tst_mathutils.cpp index 30d2d8d6c5..a585868d99 100644 --- a/tests/auto/utils/mathutils/tst_mathutils.cpp +++ b/tests/auto/utils/mathutils/tst_mathutils.cpp @@ -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" |