Skip to content

Commit 18bce3a

Browse files
committed
Math/Easing
1 parent b1b1192 commit 18bce3a

File tree

6 files changed

+162
-2
lines changed

6 files changed

+162
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
- [`ChronoLogger`](modules/Log/ChronoLogger.mpp) - RAII timer that logs elapsed time at scope exit
6363

6464
### 🧮 Math
65+
- [`Easing`](modules/Math/Easing.mpp) - Collection of easing functions for smooth animation
6566
- [`Random`](modules/Math/Random.mpp) - Pseudorandom number generation
6667
- [`Utility`](modules/Math/Utility.mpp) - Floating-point comparison with epsilon tolerance
6768

modules/Execution/EventDispatcher.mpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export namespace CppUtils::Execution
2121
{
2222
auto payload = std::make_tuple(args...);
2323
for (auto& function : subscriberIt->second)
24-
function(&payload);
24+
function(std::addressof(payload));
2525
}
2626
}
2727

modules/Math/Easing.mpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
export module CppUtils.Math.Easing;
2+
3+
import std;
4+
import CppUtils.Type.Concept;
5+
import CppUtils.Math.Utility;
6+
7+
export namespace CppUtils::Math::Easing
8+
{
9+
[[nodiscard]] constexpr auto inQuad(std::floating_point auto value) noexcept -> auto
10+
{
11+
return value * value;
12+
}
13+
14+
[[nodiscard]] constexpr auto outQuad(std::floating_point auto value) noexcept -> auto
15+
{
16+
return value * (2 - value);
17+
}
18+
19+
[[nodiscard]] constexpr auto inOutQuad(std::floating_point auto value) noexcept -> auto
20+
{
21+
return value < 0.5 ? 2 * value * value : -1 + (4 - 2 * value) * value;
22+
}
23+
24+
[[nodiscard]] constexpr auto inCubic(std::floating_point auto value) noexcept -> auto
25+
{
26+
return value * value * value;
27+
}
28+
29+
[[nodiscard]] constexpr auto outCubic(std::floating_point auto value) noexcept -> auto
30+
{
31+
auto temp = value - 1;
32+
return temp * temp * temp + 1;
33+
}
34+
35+
[[nodiscard]] constexpr auto inOutCubic(std::floating_point auto value) noexcept -> auto
36+
{
37+
if (value < 0.5)
38+
return 4 * value * value * value;
39+
40+
auto temp = -2 * value + 2;
41+
return 1 - (temp * temp * temp) / 2;
42+
}
43+
44+
[[nodiscard]] constexpr auto inQuart(std::floating_point auto value) noexcept -> auto
45+
{
46+
return value * value * value * value;
47+
}
48+
49+
[[nodiscard]] constexpr auto outQuart(std::floating_point auto value) noexcept -> auto
50+
{
51+
auto temp = value - 1;
52+
return 1 - temp * temp * temp * temp;
53+
}
54+
55+
[[nodiscard]] constexpr auto inOutQuart(std::floating_point auto value) noexcept -> auto
56+
{
57+
if (value < 0.5)
58+
return 8 * value * value * value * value;
59+
60+
auto temp = -2 * value + 2;
61+
return 1 - (temp * temp * temp * temp) / 2;
62+
}
63+
64+
[[nodiscard]] constexpr auto inQuint(std::floating_point auto value) noexcept -> auto
65+
{
66+
return value * value * value * value * value;
67+
}
68+
69+
[[nodiscard]] constexpr auto outQuint(std::floating_point auto value) noexcept -> auto
70+
{
71+
auto temp = value - 1;
72+
return 1 + temp * temp * temp * temp * temp;
73+
}
74+
75+
[[nodiscard]] constexpr auto inOutQuint(std::floating_point auto value) noexcept -> auto
76+
{
77+
if (value < 0.5)
78+
return 16 * value * value * value * value * value;
79+
80+
auto temp = -2 * value + 2;
81+
return 1 - (temp * temp * temp * temp * temp) / 2;
82+
}
83+
84+
[[nodiscard]] constexpr auto inSine(std::floating_point auto value) noexcept -> auto
85+
{
86+
return 1 - std::cos((value * std::numbers::pi_v<decltype(value)>) / 2);
87+
}
88+
89+
[[nodiscard]] constexpr auto outSine(std::floating_point auto value) noexcept -> auto
90+
{
91+
return std::sin((value * std::numbers::pi_v<decltype(value)>) / 2);
92+
}
93+
94+
[[nodiscard]] constexpr auto inOutSine(std::floating_point auto value) noexcept -> auto
95+
{
96+
return -(std::cos(std::numbers::pi_v<decltype(value)> * value) - 1) / 2;
97+
}
98+
99+
[[nodiscard]] constexpr auto inCirc(std::floating_point auto value) noexcept -> auto
100+
{
101+
return 1 - std::sqrt(1 - std::pow(value, 2));
102+
}
103+
104+
[[nodiscard]] constexpr auto outCirc(std::floating_point auto value) noexcept -> auto
105+
{
106+
return std::sqrt(1 - (value - 1) * (value - 1));
107+
}
108+
109+
[[nodiscard]] constexpr auto inOutCirc(std::floating_point auto value) noexcept -> auto
110+
{
111+
if (value < 0.5)
112+
return (1 - std::sqrt(1 - 4 * value * value)) / 2;
113+
114+
auto temp = -2 * value + 2;
115+
return (std::sqrt(1 - temp * temp) + 1) / 2;
116+
}
117+
}

modules/Math/Math.mpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export module CppUtils.Math;
22

33
export import CppUtils.Math.Concept;
4+
export import CppUtils.Math.Easing;
45
export import CppUtils.Math.Endian;
56
export import CppUtils.Math.Random;
67
export import CppUtils.Math.Utility;

modules/Math/Utility.mpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ export namespace CppUtils::Math
2727
static_assert(absolute(0u) == 0u);
2828
static_assert(absolute(1u) == 1u);
2929

30+
template<std::floating_point Float>
31+
[[nodiscard]] inline constexpr auto isEqual(Float lhs, Float rhs, Float epsilon = std::numeric_limits<Float>::epsilon()) noexcept -> bool
32+
{
33+
auto difference = absolute(lhs - rhs);
34+
auto maximum = std::max(absolute(lhs), absolute(rhs));
35+
if (maximum >= Float{1})
36+
return difference <= epsilon * maximum;
37+
else if (maximum > Float{0})
38+
return difference / maximum <= epsilon;
39+
return true;
40+
}
41+
42+
static_assert(isEqual(0.0, 0.0));
43+
static_assert(isEqual(0.1 + 0.2, 0.3));
44+
static_assert(not isEqual(0.1 + 0.2, 0.29));
45+
static_assert(not isEqual(0.1 + 0.2, 0.31));
46+
3047
template<Type::Numeric T>
3148
[[nodiscard]] inline constexpr auto isBetween(T value, T low, T high) noexcept -> bool
3249
{

tests/Terminal/Canvas.mpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import CppUtils;
55

66
export namespace CppUtils::UnitTest::Terminal::Canvas
77
{
8-
inline auto _ = TestSuite{"Terminal/Canvas", {"UnitTest", "Thread/Scheduler"}, [](auto& suite) {
8+
inline auto _ = TestSuite{"Terminal/Canvas", {"UnitTest", "Thread/Scheduler", "Math/Easing"}, [](auto& suite) {
99
using namespace std::literals;
1010
using namespace std::chrono_literals;
1111

@@ -84,6 +84,30 @@ export namespace CppUtils::UnitTest::Terminal::Canvas
8484
canvas.wait();
8585
});
8686

87+
suite.addTest("Multiple Progress Bars", [&] {
88+
auto canvas = CppUtils::Terminal::v2::Canvas{CppUtils::Container::Size2{50, 3}};
89+
auto& layout = canvas.addWidget(std::make_unique<CppUtils::Terminal::Layout>());
90+
91+
auto& bar1 = layout.addWidget(std::make_unique<CppUtils::Terminal::ProgressBar>("Bar 1"));
92+
auto& bar2 = layout.addWidget(std::make_unique<CppUtils::Terminal::ProgressBar>("Bar 2"));
93+
auto& bar3 = layout.addWidget(std::make_unique<CppUtils::Terminal::ProgressBar>("Bar 3"));
94+
95+
auto scheduler = CppUtils::Thread::Scheduler{};
96+
scheduler.schedule([&canvas]() mutable {
97+
canvas.close();
98+
}, 500ms);
99+
100+
for (auto i = 0.f; i <= 100.f; i += 2.f)
101+
{
102+
bar1.setPercent(i);
103+
bar2.setPercent(CppUtils::Math::Easing::inQuad(i / 100.f) * 100.f);
104+
bar3.setPercent(CppUtils::Math::Easing::outCubic(i / 100.f) * 100.f);
105+
std::this_thread::sleep_for(5ms);
106+
}
107+
108+
canvas.wait();
109+
});
110+
87111
suite.addTest("Bouncing ball", [&] {
88112
const auto terminalSize = CppUtils::Terminal::getTerminalSize();
89113
auto canvasSize = terminalSize;

0 commit comments

Comments
 (0)