diff --git a/include/misc/Easing.h b/include/misc/Easing.h new file mode 100644 index 0000000..ed1cdae --- /dev/null +++ b/include/misc/Easing.h @@ -0,0 +1,67 @@ +#pragma once + +namespace td { +namespace utils{ + +/* Sine functions */ + +float easeInSine(float x); +float easeOutSine(float x); +float easeInOutSine(float x); + +/* Cubic functions */ + +float easeInCubic(float x); +float easeOutCubic(float x); +float easeInOutCubic(float x); + +/* Quint functions */ + +float easeInQuint(float x); +float easeOutQuint(float x); +float easeInOutQuint(float x); + +/* Circ functions */ + +float easeInCirc(float x); +float easeOutCirc(float x); +float easeInOutCirc(float x); + +/* Elastic functions */ + +float easeInElastic(float x); +float easeOutElastic(float x); +float easeInOutElastic(float x); + +/* Quad functions */ + +float easeInQuad(float x); +float easeOutQuad(float x); +float easeInOutQuad(float x); + +/* Quart functions */ + +float easeInQuart(float x); +float easeOutQuart(float x); +float easeInOutQuart(float x); + +/* Expo functions */ + +float easeInExpo(float x); +float easeOutExpo(float x); +float easeInOutExpo(float x); + +/* Back functions */ + +float easeInBack(float x); +float easeOutBack(float x); +float easeInOutBack(float x); + +/* Bounce functions */ + +float easeInBounce(float x); +float easeOutBounce(float x); +float easeInOutBounce(float x); + +} // namespace utils +} // namespace td diff --git a/src/misc/Easing.cpp b/src/misc/Easing.cpp new file mode 100644 index 0000000..32e6260 --- /dev/null +++ b/src/misc/Easing.cpp @@ -0,0 +1,200 @@ +#include "misc/Easing.h" + +#include + +namespace td{ +namespace utils{ + +/* Sine functions */ + +float easeInSine(float x){ + return 1.0f - std::cos((x * M_PI) / 2.0f); +} + +float easeOutSine(float x){ + return std::sin((x * M_PI) / 2.0f); +} + +float easeInOutSine(float x){ + return -(std::cos(M_PI * x) - 1.0f) / 2.0f; +} + +/* Cubic functions */ + +float easeInCubic(float x){ + return x * easeInQuad(x); +} + +float easeOutCubic(float x){ + return 1 - std::pow(1 - x, 3); +} + +float easeInOutCubic(float x){ + return x < 0.5 ? 4 * easeInCubic(x) : 1 - std::pow(-2 * x + 2, 3) / 2.0f; +} + +/* Quint functions */ + +float easeInQuint(float x){ + return x * easeInQuart(x); +} + +float easeOutQuint(float x){ + return 1 - std::pow(1 - x, 5); +} + +float easeInOutQuint(float x){ + return x < 0.5 ? 16 * easeInQuint(x) : 1 - std::pow(-2 * x + 2, 5) / 2.0f; +} + +/* Circ functions */ + +float easeInCirc(float x){ + return 1 - std::sqrt(1 - std::pow(x, 2)); +} + +float easeOutCirc(float x){ + return std::sqrt(1 - std::pow(x - 1, 2)); +} + +float easeInOutCirc(float x){ + return x < 0.5 + ? (1 - std::sqrt(1 - std::pow(2 * x, 2))) / 2.0f + : (std::sqrt(1 - std::pow(-2 * x + 2, 2)) + 1) / 2.0f; +} + +/* Elastic functions */ + +float easeInElastic(float x){ + const float c4 = (2 * M_PI) / 3.0f; + + return x == 0 + ? 0 + : x == 1 + ? 1 + : -std::pow(2, 10 * x - 10) * std::sin((x * 10 - 10.75) * c4); +} + +float easeOutElastic(float x){ + const float c4 = (2 * M_PI) / 3.0f; + + return x == 0 + ? 0 + : x == 1 + ? 1 + : std::pow(2, -10 * x) * std::sin((x * 10 - 0.75) * c4) + 1; +} + +float easeInOutElastic(float x){ + const float c5 = (2 * M_PI) / 4.5; + + return x == 0 + ? 0 + : x == 1 + ? 1 + : x < 0.5 + ? -(std::pow(2, 20 * x - 10) * std::sin((20 * x - 11.125) * c5)) / 2.0f + : (std::pow(2, -20 * x + 10) * std::sin((20 * x - 11.125) * c5)) / 2.0f + 1; +} + +/* Quad functions */ + +float easeInQuad(float x){ + return x * x; +} + +float easeOutQuad(float x){ + return 1 - (1 - x) * (1 - x); +} + +float easeInOutQuad(float x){ + return x < 0.5 ? 2 * x * x : 1 - std::pow(-2 * x + 2, 2) / 2.0f; +} + +/* Quart functions */ + +float easeInQuart(float x){ + return x * easeInCubic(x); +} + +float easeOutQuart(float x){ + return 1 - std::pow(1 - x, 4); +} + +float easeInOutQuart(float x){ + return x < 0.5 ? 8 * easeInQuart(x) : 1 - std::pow(-2 * x + 2, 4) / 2.0f; +} + +/* Expo functions */ + +float easeInExpo(float x){ + return x == 0 ? 0 : std::pow(2, 10 * x - 10); +} + +float easeOutExpo(float x){ + return x == 1 ? 1 : 1 - std::pow(2, -10 * x); +} + +float easeInOutExpo(float x){ + return x == 0 + ? 0 + : x == 1 + ? 1 + : x < 0.5 ? std::pow(2, 20 * x - 10) / 2.0f + : (2 - std::pow(2, -20 * x + 10)) / 2.0f; +} + +/* Back functions */ + +float easeInBack(float x){ + const float c1 = 1.70158; + const float c3 = c1 + 1; + + return c3 * easeInCubic(x) - c1 * easeInQuad(x); +} + +float easeOutBack(float x){ + const float c1 = 1.70158; + const float c3 = c1 + 1; + + return 1 + c3 * std::pow(x - 1, 3) + c1 * std::pow(x - 1, 2); +} + +float easeInOutBack(float x){ + const float c1 = 1.70158; + const float c2 = c1 * 1.525; + + return x < 0.5 + ? (std::pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2.0f + : (std::pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2.0f; +} + +/* Bounce functions */ + +float easeInBounce(float x){ + return 1 - easeOutBounce(1 - x); +} + +float easeOutBounce(float x){ + const float n1 = 7.5625; + const float d1 = 2.75; + + if (x < 1 / d1) { + return n1 * easeInQuad(x); + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } +} + +float easeInOutBounce(float x){ + return x < 0.5 + ? (1 - easeOutBounce(1 - 2 * x)) / 2.0f + : (1 + easeOutBounce(2 * x - 1)) / 2.0f; +} + +} // namespace utils +} // namespace td