fix(comments): soften "bit-exact" to "~1e-15 floating-point rounding" in velocity_curve
This commit is contained in:
@@ -97,8 +97,8 @@ namespace {
|
||||
// The rule: a tangent whose adjacent secants have opposite signs (or either is flat) is a local
|
||||
// extremum — pin the tangent to 0 so the curve does not overshoot past the knot. Otherwise use the
|
||||
// weighted-harmonic-mean tangent (Fritsch–Carlson eq. 4), which for COLLINEAR knots (dPrev==dNext)
|
||||
// reduces EXACTLY to that common secant — so collinear control points reproduce the straight line
|
||||
// bit-for-bit (the Option-B / null-response contract that linear() must still satisfy).
|
||||
// reduces to that common secant — so collinear control points reproduce the straight line to within
|
||||
// floating-point rounding (~1e-15), preserving the Option-B / null-response contract for linear().
|
||||
double fritschCarlsonTangent(double dPrev, double dNext, double spanPrev, double spanNext) {
|
||||
if (dPrev * dNext <= 0.0) return 0.0; // sign change or a flat neighbour -> local extremum
|
||||
// Weighted harmonic mean of the two secants (weights = the two segment widths). Collinear case:
|
||||
@@ -131,8 +131,9 @@ double VelocityCurve::eval(double velocity) const {
|
||||
// --- Monotone cubic Hermite (Fritsch–Carlson) interpolation on segment [a,b] ---------
|
||||
// Curved (spline) response, not straight lines. The interpolant provably stays within
|
||||
// [a.amp, b.amp] between the two knots (no bulge below 0 / above 1), and for collinear
|
||||
// control points its tangents reduce to the secant slope — so it IS the straight line,
|
||||
// keeping linear() an EXACT y = velocity/127 (the null-response contract).
|
||||
// control points its tangents reduce to the secant slope — so it reproduces the straight
|
||||
// line to within floating-point rounding (~1e-15), preserving linear()'s null-response
|
||||
// contract (y = velocity/127 to ~1e-15; the test tolerance of 1e-12 is appropriate).
|
||||
const double d = (b.amp - a.amp) / span; // secant of THIS segment
|
||||
|
||||
// Tangent at a: 0 if a is the first knot (endpoint), else the FC-limited tangent using
|
||||
@@ -161,7 +162,8 @@ double VelocityCurve::eval(double velocity) const {
|
||||
}
|
||||
|
||||
// Cubic Hermite basis on the normalized position t across [a,b]. For collinear knots
|
||||
// mA==mB==d, so h00*a + (h10*span)*d + h01*b + (h11*span)*d collapses to the exact line.
|
||||
// mA==mB==d, so h00*a + (h10*span)*d + h01*b + (h11*span)*d collapses to the straight
|
||||
// line to within floating-point rounding (~1e-15).
|
||||
const double t = (v - a.velocity) / span;
|
||||
const double t2 = t * t;
|
||||
const double t3 = t2 * t;
|
||||
|
||||
Reference in New Issue
Block a user