import { desaturate } from './render_geo.mjs'; function t_from_ratio(ratio) { return Math.min(Math.max((ratio - 1) / 0.4, 0), 1); } // Hue-wheel position (0-1) → RGB at full saturation and value. function hue_to_rgb(h) { const s = 6 * (h % 1); const i = Math.floor(s); const f = s - i; const q = 1 - f; if (i === 0) { return [1, f, 0]; } if (i === 1) { return [q, 1, 0]; } if (i === 2) { return [0, 1, f]; } if (i === 3) { return [0, q, 1]; } if (i === 4) { return [f, 0, 1]; } return [1, 0, q]; } export const PALETTES = [ { id: 'classic', name: 'Classic', face_color(ratio, is_pentagon) { if (is_pentagon) { return desaturate([1.0, 0.85, 0.23], 0.45); } const t = t_from_ratio(ratio); return desaturate([Math.min(1, 2*t), t < 0.5 ? t*1.4 : 0.7-(t-0.5)*1.4, Math.max(0, 1-2*t)], 0.45); }, }, { id: 'vibrant', name: 'Vibrant', face_color(ratio, is_pentagon) { if (is_pentagon) { return [1.0, 0.82, 0.10]; } const t = t_from_ratio(ratio); return [Math.min(1, 2*t), t < 0.5 ? t*1.4 : 0.7-(t-0.5)*1.4, Math.max(0, 1-2*t)]; }, }, { id: 'arctic', name: 'Arctic', // Low distortion = pale ice blue, high = deep indigo. face_color(ratio, is_pentagon) { if (is_pentagon) { return [0.95, 0.75, 0.20]; } const t = t_from_ratio(ratio); return desaturate([ 0.55 - t * 0.45, 0.80 - t * 0.50, 1.0 - t * 0.15, ], 0.7 + t * 0.3); }, }, { id: 'ember', name: 'Ember', // Low distortion = dark red, high = bright yellow-white. face_color(ratio, is_pentagon) { if (is_pentagon) { return desaturate([0.25, 0.55, 0.85], 0.6); } const t = t_from_ratio(ratio); return [ 0.35 + t * 0.65, t * t * 0.85, t * t * t * 0.25, ]; }, }, { id: 'rainbow', name: 'Rainbow', // Full hue sweep: low distortion = blue (240°), high = red (0°). face_color(ratio, is_pentagon) { if (is_pentagon) { return [1.0, 1.0, 1.0]; } const t = t_from_ratio(ratio); return desaturate(hue_to_rgb(0.67 - t * 0.67), 0.85); }, }, ]; export const DEFAULT_PALETTE = PALETTES[0];