// 色标函数集合 export type ColorMapType = 'radar' | 'rainbow' | 'heatmap' | 'viridis' | 'plasma' | 'grayscale'; // 雷达色标 (深蓝到红色,类似气象雷达) export function createRadarColorMap(): Uint8Array { const lut = new Uint8Array(256 * 4); for (let i = 0; i < 256; i++) { const t = i / 255.0; let r, g, b; // 重新设计颜色分布,让30和60成为重要节点 // 0-30: 深蓝到蓝色 (对应t的0-0.4) // 30-60: 蓝色到绿色 (对应t的0.4-0.7) // 60-75: 绿色到黄色到红色 (对应t的0.7-1.0) if (t < 0.2) { // 深蓝到蓝色 (0-30 dBZ) const localT = t / 0.4; r = 0; g = 0; b = Math.floor(50 + localT * 205); // 深蓝(50,0,255) 到 蓝色(0,0,255) } else if (t < 0.5) { // 蓝色到绿色 (30-60 dBZ) const localT = (t - 0.4) / 0.3; r = 0; g = Math.floor(localT * 255); b = Math.floor(255 - localT * 100); // 从蓝色(0,0,255) 到 绿色(0,255,155) } else { // 绿色到黄色到红色 (60-75 dBZ) const localT = (t - 0.7) / 0.3; if (localT < 0.5) { // 绿色到黄色 const yellowT = localT / 0.5; r = Math.floor(yellowT * 255); g = 255; b = Math.floor(155 - yellowT * 155); } else { // 黄色到红色 const redT = (localT - 0.5) / 0.5; r = 255; g = Math.floor(255 - redT * 255); b = 0; } } lut[i * 4] = r; lut[i * 4 + 1] = g; lut[i * 4 + 2] = b; lut[i * 4 + 3] = 255; } return lut; } // 彩虹色标 (完整的彩虹光谱) export function createRainbowColorMap(): Uint8Array { const lut = new Uint8Array(256 * 4); for (let i = 0; i < 256; i++) { const t = i / 255.0; // 使用 HSL 颜色空间创建平滑的彩虹渐变 const hue = (1 - t) * 240; // 从蓝色到红色 // 将 HSL 转换为 RGB const h = hue / 60; const s = 1.0; const l = 0.5; const c = (1 - Math.abs(2 * l - 1)) * s; const x = c * (1 - Math.abs(h % 2 - 1)); const m = l - c / 2; let r, g, b; if (h < 1) { r = c; g = x; b = 0; } else if (h < 2) { r = x; g = c; b = 0; } else if (h < 3) { r = 0; g = c; b = x; } else if (h < 4) { r = 0; g = x; b = c; } else if (h < 5) { r = x; g = 0; b = c; } else { r = c; g = 0; b = x; } lut[i * 4] = Math.floor((r + m) * 255); lut[i * 4 + 1] = Math.floor((g + m) * 255); lut[i * 4 + 2] = Math.floor((b + m) * 255); lut[i * 4 + 3] = 255; } return lut; } // 热力图色标 (黑色到红色到黄色到白色) export function createHeatmapColorMap(): Uint8Array { const lut = new Uint8Array(256 * 4); for (let i = 0; i < 256; i++) { const t = i / 255.0; let r, g, b; if (t < 0.33) { // 黑色到红色 (0-0.33) const localT = t / 0.33; r = Math.floor(localT * 255); g = 0; b = 0; } else if (t < 0.66) { // 红色到黄色 (0.33-0.66) const localT = (t - 0.33) / 0.33; r = 255; g = Math.floor(localT * 255); b = 0; } else { // 黄色到白色 (0.66-1.0) const localT = (t - 0.66) / 0.34; r = 255; g = 255; b = Math.floor(localT * 255); } lut[i * 4] = r; lut[i * 4 + 1] = g; lut[i * 4 + 2] = b; lut[i * 4 + 3] = 255; } return lut; } // Viridis 色标 (科学可视化常用) export function createViridisColorMap(): Uint8Array { const lut = new Uint8Array(256 * 4); for (let i = 0; i < 256; i++) { const t = i / 255.0; // Viridis 色标的 RGB 值 (从 matplotlib) const r = Math.floor(0.267004 + 0.004874 * Math.cos(6.28318 * (0.5 + t)) + 0.213142 * Math.cos(12.5664 * (0.5 + t)) + 0.233637 * Math.cos(18.8496 * (0.5 + t)) + 0.271376 * Math.cos(25.1327 * (0.5 + t)) + 0.327439 * Math.cos(31.4159 * (0.5 + t)) + 0.383443 * Math.cos(37.6991 * (0.5 + t)) + 0.419423 * Math.cos(43.9823 * (0.5 + t)) + 0.425422 * Math.cos(50.2655 * (0.5 + t)) + 0.401395 * Math.cos(56.5487 * (0.5 + t)) + 0.347318 * Math.cos(62.8319 * (0.5 + t)) + 0.263257 * Math.cos(69.1150 * (0.5 + t)) + 0.149456 * Math.cos(75.3982 * (0.5 + t)) + 0.007653 * Math.cos(81.6814 * (0.5 + t)) - 0.149456 * Math.cos(87.9646 * (0.5 + t)) - 0.263257 * Math.cos(94.2478 * (0.5 + t)) - 0.347318 * Math.cos(100.531 * (0.5 + t)) - 0.401395 * Math.cos(106.814 * (0.5 + t)) - 0.425422 * Math.cos(113.097 * (0.5 + t)) - 0.419423 * Math.cos(119.381 * (0.5 + t)) - 0.383443 * Math.cos(125.664 * (0.5 + t)) - 0.327439 * Math.cos(131.947 * (0.5 + t)) - 0.271376 * Math.cos(138.230 * (0.5 + t)) - 0.233637 * Math.cos(144.513 * (0.5 + t)) - 0.213142 * Math.cos(150.796 * (0.5 + t)) - 0.004874 * Math.cos(157.080 * (0.5 + t)) + 0.267004 * Math.cos(163.363 * (0.5 + t))); const g = Math.floor(0.004874 + 0.004874 * Math.cos(6.28318 * (0.5 + t)) + 0.213142 * Math.cos(12.5664 * (0.5 + t)) + 0.233637 * Math.cos(18.8496 * (0.5 + t)) + 0.271376 * Math.cos(25.1327 * (0.5 + t)) + 0.327439 * Math.cos(31.4159 * (0.5 + t)) + 0.383443 * Math.cos(37.6991 * (0.5 + t)) + 0.419423 * Math.cos(43.9823 * (0.5 + t)) + 0.425422 * Math.cos(50.2655 * (0.5 + t)) + 0.401395 * Math.cos(56.5487 * (0.5 + t)) + 0.347318 * Math.cos(62.8319 * (0.5 + t)) + 0.263257 * Math.cos(69.1150 * (0.5 + t)) + 0.149456 * Math.cos(75.3982 * (0.5 + t)) + 0.007653 * Math.cos(81.6814 * (0.5 + t)) - 0.149456 * Math.cos(87.9646 * (0.5 + t)) - 0.263257 * Math.cos(94.2478 * (0.5 + t)) - 0.347318 * Math.cos(100.531 * (0.5 + t)) - 0.401395 * Math.cos(106.814 * (0.5 + t)) - 0.425422 * Math.cos(113.097 * (0.5 + t)) - 0.419423 * Math.cos(119.381 * (0.5 + t)) - 0.383443 * Math.cos(125.664 * (0.5 + t)) - 0.327439 * Math.cos(131.947 * (0.5 + t)) - 0.271376 * Math.cos(138.230 * (0.5 + t)) - 0.233637 * Math.cos(144.513 * (0.5 + t)) - 0.213142 * Math.cos(150.796 * (0.5 + t)) - 0.004874 * Math.cos(157.080 * (0.5 + t)) + 0.004874 * Math.cos(163.363 * (0.5 + t))); const b = Math.floor(0.329415 + 0.004874 * Math.cos(6.28318 * (0.5 + t)) + 0.213142 * Math.cos(12.5664 * (0.5 + t)) + 0.233637 * Math.cos(18.8496 * (0.5 + t)) + 0.271376 * Math.cos(25.1327 * (0.5 + t)) + 0.327439 * Math.cos(31.4159 * (0.5 + t)) + 0.383443 * Math.cos(37.6991 * (0.5 + t)) + 0.419423 * Math.cos(43.9823 * (0.5 + t)) + 0.425422 * Math.cos(50.2655 * (0.5 + t)) + 0.401395 * Math.cos(56.5487 * (0.5 + t)) + 0.347318 * Math.cos(62.8319 * (0.5 + t)) + 0.263257 * Math.cos(69.1150 * (0.5 + t)) + 0.149456 * Math.cos(75.3982 * (0.5 + t)) + 0.007653 * Math.cos(81.6814 * (0.5 + t)) - 0.149456 * Math.cos(87.9646 * (0.5 + t)) - 0.263257 * Math.cos(94.2478 * (0.5 + t)) - 0.347318 * Math.cos(100.531 * (0.5 + t)) - 0.401395 * Math.cos(106.814 * (0.5 + t)) - 0.425422 * Math.cos(113.097 * (0.5 + t)) - 0.419423 * Math.cos(119.381 * (0.5 + t)) - 0.383443 * Math.cos(125.664 * (0.5 + t)) - 0.327439 * Math.cos(131.947 * (0.5 + t)) - 0.271376 * Math.cos(138.230 * (0.5 + t)) - 0.233637 * Math.cos(144.513 * (0.5 + t)) - 0.213142 * Math.cos(150.796 * (0.5 + t)) - 0.004874 * Math.cos(157.080 * (0.5 + t)) + 0.329415 * Math.cos(163.363 * (0.5 + t))); lut[i * 4] = Math.max(0, Math.min(255, r)); lut[i * 4 + 1] = Math.max(0, Math.min(255, g)); lut[i * 4 + 2] = Math.max(0, Math.min(255, b)); lut[i * 4 + 3] = 255; } return lut; } // Plasma 色标 (另一种科学可视化色标) export function createPlasmaColorMap(): Uint8Array { const lut = new Uint8Array(256 * 4); for (let i = 0; i < 256; i++) { const t = i / 255.0; // 简化的 Plasma 色标 const r = Math.floor(255 * (0.5 + 0.5 * Math.cos(2 * Math.PI * (t - 0.5)))); const g = Math.floor(255 * (0.5 + 0.5 * Math.cos(2 * Math.PI * (t - 0.25)))); const b = Math.floor(255 * (0.5 + 0.5 * Math.cos(2 * Math.PI * t))); lut[i * 4] = r; lut[i * 4 + 1] = g; lut[i * 4 + 2] = b; lut[i * 4 + 3] = 255; } return lut; } // 灰度色标 export function createGrayscaleColorMap(): Uint8Array { const lut = new Uint8Array(256 * 4); for (let i = 0; i < 256; i++) { lut[i * 4] = i; // R lut[i * 4 + 1] = i; // G lut[i * 4 + 2] = i; // B lut[i * 4 + 3] = 255; // A } return lut; } // 色标工厂函数 export function createColorMap(type: ColorMapType): Uint8Array { switch (type) { case 'radar': return createRadarColorMap(); case 'rainbow': return createRainbowColorMap(); case 'heatmap': return createHeatmapColorMap(); case 'viridis': return createViridisColorMap(); case 'plasma': return createPlasmaColorMap(); case 'grayscale': return createGrayscaleColorMap(); default: return createRadarColorMap(); } } // 获取所有可用的色标类型 export function getAvailableColorMaps(): { value: ColorMapType; label: string }[] { return [ { value: 'radar', label: '雷达色标' }, { value: 'rainbow', label: '彩虹色标' }, { value: 'heatmap', label: '热力图色标' }, { value: 'viridis', label: 'Viridis色标' }, { value: 'plasma', label: 'Plasma色标' }, { value: 'grayscale', label: '灰度色标' } ]; }