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];
|
||||
};
|
||||
@@ -1780,6 +1780,7 @@
|
||||
4B83348E1F5DBA6E0097E338 /* 6522Storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = 6522Storage.hpp; path = Implementation/6522Storage.hpp; sourceTree = "<group>"; };
|
||||
4B8334911F5E24FF0097E338 /* C1540Base.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = C1540Base.hpp; path = Implementation/C1540Base.hpp; sourceTree = "<group>"; };
|
||||
4B8334941F5E25B60097E338 /* C1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = C1540.cpp; path = Implementation/C1540.cpp; sourceTree = "<group>"; };
|
||||
4B847B9F2E920C7500774B9B /* CubicCurve.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = CubicCurve.hpp; path = /Users/thomasharte/Projects/CLK/Numeric/CubicCurve.hpp; sourceTree = "<absolute>"; };
|
||||
4B85322922778E4200F26553 /* Comparative68000.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Comparative68000.hpp; sourceTree = "<group>"; };
|
||||
4B85322E2277ABDD00F26553 /* tos100.trace.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = tos100.trace.txt.gz; sourceTree = "<group>"; };
|
||||
4B8671EA2D8B40D8009E1610 /* Descriptors.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Descriptors.hpp; sourceTree = "<group>"; };
|
||||
@@ -3147,6 +3148,7 @@
|
||||
4BD191D5219113B80042E144 /* OpenGL */,
|
||||
4BB8616B24E22DC500A00E03 /* ScanTargets */,
|
||||
4BD060A41FE49D3C006E14BE /* Speaker */,
|
||||
4B847B9F2E920C7500774B9B /* CubicCurve.hpp */,
|
||||
);
|
||||
name = Outputs;
|
||||
path = ../../Outputs;
|
||||
|
||||
Reference in New Issue
Block a user