aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2022-11-28 11:28:49 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2022-11-28 10:45:13 +0000
commit12b639970fc3ce08eada69d315470735fc23ef5f (patch)
tree9a8c162d2229fd8dfac9f10f11ed47446d047379
parent23f53dcbda305d3e2f593b4e0c566375af7dc0fb (diff)
MathUtils: Add exponential interpolation
Change-Id: I58bb26a6e921cbd1f5532bddcd6a6700ff80b94f Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--src/libs/utils/mathutils.cpp25
-rw-r--r--src/libs/utils/mathutils.h3
-rw-r--r--tests/auto/utils/mathutils/tst_mathutils.cpp27
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"