1
0
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:
Thomas Harte
2025-10-04 22:26:09 -04:00
parent 6b437c3907
commit 239cc15c8f
2 changed files with 71 additions and 0 deletions

69
Numeric/CubicCurve.hpp Normal file
View 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];
};

View File

@@ -1780,6 +1780,7 @@
4B83348E1F5DBA6E0097E338 /* 6522Storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = 6522Storage.hpp; path = Implementation/6522Storage.hpp; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 4B8671EA2D8B40D8009E1610 /* Descriptors.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Descriptors.hpp; sourceTree = "<group>"; };
@@ -3147,6 +3148,7 @@
4BD191D5219113B80042E144 /* OpenGL */, 4BD191D5219113B80042E144 /* OpenGL */,
4BB8616B24E22DC500A00E03 /* ScanTargets */, 4BB8616B24E22DC500A00E03 /* ScanTargets */,
4BD060A41FE49D3C006E14BE /* Speaker */, 4BD060A41FE49D3C006E14BE /* Speaker */,
4B847B9F2E920C7500774B9B /* CubicCurve.hpp */,
); );
name = Outputs; name = Outputs;
path = ../../Outputs; path = ../../Outputs;