Consolidate Ink's linear interpolation implementations #399
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Consolidate Ink's linear interpolation implementations
We had multiple different naive floating-point lerp implementations sprinkled throughout our code. In some places, we used
a + (b - a) * t, which gives incorrect results ifb - aoverflows, and can be inexact fort = 1. In other places, we useda * (1 - t) + b * t, which is better, but apparently has monotonicity issues [1] and also gives incorrect results whentis infinite andaorbis zero. Better to have one carefully tested definition and use it everywhere, which is what this CL does.The good news is that C++20 (which we can finally now use in all our build environments) provides a
std::lerpfunction that handles these edge cases. The bad news is that (at least in some of our build environments), it seems to have a bug (b/457491215) where its behavior does not match the standard! So for now ourfloat Lerpdefinition in this CL has an extra branch to work around that before deferring tostd::lerp.[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html