Open Fil opened 4 years ago
@danburzo if you'd like to review?
I think I'd like to revisit the boundary conditions (section 2.2 in the Steffen paper). It seems we're duplicating the slopes at either ends by adding the reflection of arr[1]
across arr[0]
and the reflection of arr[arr.length - 2]
across arr[arr.length-1]
and that makes intuitive / naive sense to me, but I'm not entirely convinced it matches either the suggestions in the paper or the curve implementation in d3-shape
, which (I think) implements equation (24), that is takes the first three values into account rather than just two.
See also https://github.com/d3/d3-shape/issues/118 #52 #67
I had a chance to give the cited paper another look. The previous implementation in culori, and by extension, in this PR, is using the one-sided finite differences for boundary points, which is a valid approach outlined in the paper (Section 2.2).
In culori@0.16.0
, I added another implementation to use equations (24) to (27) instead as culori.interpolatorSplineMonotone2
. The effect is different but not necessarily better for color interpolation:
(In the image above, the FD versions refer to 'one-sided finite differences')
In particular, the finite-differences approach (blue stroke in the image below) produces curves that are closer to a linear interpolation; the new implementation (red stroke) tends to squeeze the colors at either end of the interpolation into a narrower portion:
So I'm not 100% convinced the new approach produces better results...
cubic Hermite splines ; will be useful for https://github.com/d3/d3-scale-chromatic/issues/28
The difference with interpolateBasis is that this interpolator returns the exact values at the control points; with n = values.length we have:
Code adapted from https://github.com/Evercoder/culori (see https://github.com/Evercoder/culori/issues/91 )