d3 / d3-interpolate

Interpolate numbers, colors, strings, arrays, objects, whatever!
https://d3js.org/d3-interpolate
ISC License
494 stars 69 forks source link

interpolateCubic, interpolateCubicClosed, interpolateMonotone, interpolateMonotoneClosed #87

Open Fil opened 4 years ago

Fil commented 4 years ago

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 )

Fil commented 4 years ago

@danburzo if you'd like to review?

danburzo commented 4 years ago

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.

Fil commented 4 years ago

See also https://github.com/d3/d3-shape/issues/118 #52 #67

danburzo commented 4 years ago

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:

Screenshot 2020-08-25 at 00 18 44

(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:

Screenshot 2020-08-25 at 00 16 40

So I'm not 100% convinced the new approach produces better results...