5392320Interactive illustration of Floater-Hormann barycentric rational interpolationJeremy Magland 1// Colours, assigned by the job each one does. Validated against the dark chart
2// surface #151a21 with the data-viz validator:
3//
4// categorical, all pairs r / polynomial / spline worst CVD dE 9.4
5// categorical, all pairs r / classical rational worst CVD dE 27.4
6// ordinal ramp the six steps of dRamp monotone L, gaps ok
7// diverging pair positive / negative weights worst CVD dE 19.2
8//
9// Every colour is a documented step from the reference palette; none are
10// eyeballed.
12export const surface = '#151a21'
14/** Identity: which interpolant a curve is. Fixed slots, never reassigned. */
15export const series = {
16 /** the Floater-Hormann rational interpolant */
17 r: '#3987e5',
18 /** the degree-n polynomial interpolant */
19 poly: '#d95926',
20 /** the clamped C^2 cubic spline */
21 spline: '#199e70',
22 /** the classical rational interpolant p_M / q_N */
23 classical: '#c98500',
24} as const
26/** Polarity: the sign of a barycentric weight. */
27export const diverging = {
28 pos: '#3987e5',
29 neg: '#e66767',
30 mid: '#383835',
31} as const
33/** State. A real pole is a failure, and always ships with a label and a
34 * different marker shape, never colour alone. */
35export const status = {
36 critical: '#d03b3b',
37 good: '#0ca30c',
38 warning: '#fab219',
39} as const
41/**
42 * Ordinal: position in a sequence. Used for the blend degree d, where the
43 * order is the meaning, so the reader should see it in the colour. Six steps
44 * of the blue ramp, light end kept clear of the surface.
45 */
46export const dRamp = ['#184f95', '#256abf', '#3987e5', '#6da7ec', '#9ec5f4', '#cde2fb'] as const
48export function dColor(index: number, count: number): string {
49 if (count <= 1) return dRamp[2]
50 const k = Math.round((index / (count - 1)) * (dRamp.length - 1))
51 return dRamp[Math.min(dRamp.length - 1, Math.max(0, k))]
52}
54/** Chart chrome and ink. */
55export const ink = {
56 primary: '#e6e9ef',
57 secondary: '#c3c2b7',
58 muted: '#898781',
59 grid: '#232833',
60 axis: '#38414f',
61 /** the exact function f: the reference the interpolants are measured against,
62 * deliberately not given a series slot */
63 reference: '#8b95a5',
64 /** the interpolation nodes: they belong to the data, not to any one method */
65 node: '#e8e6df',
66 /** the family of local polynomials and blending functions, drawn as a mass */
67 family: '#46536a',
68 /** the one member of that family the reader is following */
69 familyHi: '#d95926',
70} as const