mirror of
https://github.com/TomHarte/CLK.git
synced 2025-11-23 05:19:20 +00:00
Introduce cubic timing function.
This commit is contained in:
69
Numeric/CubicCurve.hpp
Normal file
69
Numeric/CubicCurve.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// CubicCurve.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 04/10/2025.
|
||||
// Copyright © 2025 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
|
||||
/*!
|
||||
Provides a cubic Bezier-based timing function.
|
||||
*/
|
||||
struct CubicCurve {
|
||||
CubicCurve(const float c1x, const float c1y, const float c2x, const float c2y) :
|
||||
c1(c1x, c1y), c2(c2x, c2y)
|
||||
{
|
||||
assert(0.0f <= c1x); assert(c1x <= 1.0f);
|
||||
assert(0.0f <= c1y); assert(c1y <= 1.0f);
|
||||
assert(0.0f <= c2x); assert(c2x <= 1.0f);
|
||||
assert(0.0f <= c2y); assert(c2y <= 1.0f);
|
||||
}
|
||||
|
||||
/// @returns A standard ease-in-out animation curve.
|
||||
static CubicCurve easeInOut() {
|
||||
return CubicCurve(0.42f, 0.0f, 0.58f, 1.0f);
|
||||
}
|
||||
|
||||
/// @returns The value for y given x, in range [0.0, 1.0].
|
||||
float value(const float x) const {
|
||||
return axis(t(x), 1);
|
||||
}
|
||||
|
||||
private:
|
||||
/// @returns The value for @c t that generates the value @c x.
|
||||
float t(const float x) const {
|
||||
static constexpr float Precision = 0.01f;
|
||||
float bounds[2] = {0.0f, 1.0f};
|
||||
const auto midpoint = [&] { return (bounds[0] + bounds[1]) * 0.5f; };
|
||||
|
||||
while(bounds[1] > bounds[0] + Precision) {
|
||||
const float mid = midpoint();
|
||||
const float value = axis(mid, 0);
|
||||
if(value > x) {
|
||||
bounds[1] = mid;
|
||||
} else {
|
||||
bounds[0] = mid;
|
||||
}
|
||||
}
|
||||
return midpoint();
|
||||
}
|
||||
|
||||
/// @returns The value for axis @c index at time @c t.
|
||||
float axis(const float t, int index) const {
|
||||
const float f1 = t * c1[index];
|
||||
const float f2 = t * c2[index] + (1.0f - t) * c1[index];
|
||||
const float f3 = t + (1.0f - t) * c2[index];
|
||||
|
||||
const float c1 = t * f2 + (1.0f - t) * f1;
|
||||
const float c2 = t * f3 + (1.0f - t) * f2;
|
||||
|
||||
return t * c2 + (1.0f - t) * c1;
|
||||
}
|
||||
|
||||
float c1[2];
|
||||
float c2[2];
|
||||
};
|
||||
Reference in New Issue
Block a user