从一个图例的色带中获取指定色值对应的数值


/**
 * 计算两个 RGBA 颜色之间的欧几里得距离
 * @param {number[]} color1 - 第一个颜色 [R, G, B, A]
 * @param {number[]} color2 - 第二个颜色 [R, G, B, A]
 * @returns {number} - 颜色距离
 */
function colorDistance(color1, color2) {
  const [r1, g1, b1, a1] = color1;
  const [r2, g2, b2, a2] = color2;
  return Math.sqrt(Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2) + Math.pow(a1 - a2, 2));
}

/**
 * 在色带中找到最接近的色值对应的数值
 * @param {number[]} targetColor - 目标颜色 [R, G, B, A]
 * @param {Array<[number, number[]]>} colorRamp - 色带,包含数值和对应的 RGBA 颜色
 * @returns {number} - 最接近的数值
 */
function findValueFromColor(targetColor, colorRamp) {
  let minDistance = Infinity;
  let closestValue = 0;

  // 遍历色带,找到最接近的颜色
  for (const [value, color] of colorRamp) {
    const distance = colorDistance(targetColor, color);
    if (distance < minDistance) {
      minDistance = distance;
      closestValue = value;
    }
  }

  return closestValue;
}

/**
 * 在色带中通过插值找到目标色值对应的数值
 * @param {number[]} targetColor - 目标颜色 [R, G, B, A]
 * @param {Array<[number, number[]]>} colorRamp - 色带,包含数值和对应的 RGBA 颜色
 * @returns {number} - 插值后的数值
 */
function findValueFromColorWithInterpolation(targetColor, colorRamp) {
  let minDistance = Infinity;
  let closestIndex = 0;

  // 找到最接近的颜色索引
  for (let i = 0; i < colorRamp.length; i++) {
    const [, color] = colorRamp[i];
    const distance = colorDistance(targetColor, color);
    if (distance < minDistance) {
      minDistance = distance;
      closestIndex = i;
    }
  }

  // 获取相邻的两个色值
  const prevIndex = Math.max(closestIndex - 1, 0);
  const nextIndex = Math.min(closestIndex + 1, colorRamp.length - 1);

  const [prevValue, prevColor] = colorRamp[prevIndex];
  const [nextValue, nextColor] = colorRamp[nextIndex];

  // 计算目标色值在两个相邻色值之间的比例
  const prevDistance = colorDistance(targetColor, prevColor);
  const nextDistance = colorDistance(targetColor, nextColor);
  const totalDistance = prevDistance + nextDistance;

  // 插值计算数值
  if (totalDistance === 0) {
    return prevValue; // 如果距离为 0,直接返回前一个值
  }
  const t = nextDistance / totalDistance;
  return prevValue + t * (nextValue - prevValue);
}

图例示例如下:

[
      [0, [0, 0, 0, 0]],
      [10.0, [1, 160, 246, 1]],
      [10.5, [1, 164, 246, 1]],
      [11.0, [1, 168, 245, 1]],
      [11.5, [1, 172, 245, 1]],
      [12.0, [1, 176, 244, 1]],
      [12.5, [1, 180, 243, 1]],
      [13.0, [1, 184, 243, 1]],
      [13.5, [1, 188, 242, 1]],
      [14.0, [1, 192, 242, 1]],
      [14.5, [1, 196, 241, 1]],
      [15.0, [0, 236, 236, 1]],
      [15.5, [0, 232, 236, 1]],
      [16.0, [0, 228, 236, 1]],
      [16.5, [0, 224, 236, 1]],
      [17.0, [0, 220, 236, 1]],
      [17.5, [0, 216, 236, 1]],
      [18.0, [0, 212, 236, 1]],
      [18.5, [0, 208, 236, 1]],
      [19.0, [0, 204, 236, 1]],
      [19.5, [0, 200, 236, 1]],
      [20.0, [0, 216, 0, 1]],
      [20.5, [0, 212, 0, 1]],
      [21.0, [0, 206, 0, 1]],
      [21.5, [0, 202, 0, 1]],
      [22.0, [0, 198, 0, 1]],
      [22.5, [0, 194, 0, 1]],
      [23.0, [0, 190, 0, 1]],
      [23.5, [0, 186, 0, 1]],
      [24.0, [0, 182, 0, 1]],
      [24.5, [0, 178, 0, 1]],
      [25.0, [1, 144, 0, 1]],
      [25.5, [1, 140, 0, 1]],
      [26.0, [1, 136, 0, 1]],
      [26.5, [1, 132, 0, 1]],
      [27.0, [1, 128, 0, 1]],
      [27.5, [1, 124, 0, 1]],
      [28.0, [1, 120, 0, 1]],
      [28.5, [1, 116, 0, 1]],
      [29.0, [1, 112, 0, 1]],
      [29.5, [1, 108, 0, 1]],
      [30.0, [255, 255, 0, 1]],
      [30.5, [254, 253, 0, 1]],
      [31.0, [253, 250, 0, 1]],
      [31.5, [252, 247, 0, 1]],
      [32.0, [251, 243, 0, 1]],
      [32.5, [250, 240, 0, 1]],
      [33.0, [249, 237, 0, 1]],
      [33.5, [248, 233, 0, 1]],
      [34.0, [247, 230, 0, 1]],
      [34.5, [246, 227, 0, 1]],
      [35.0, [231, 192, 0, 1]],
      [35.5, [232, 188, 0, 1]],
      [36.0, [233, 184, 0, 1]],
      [36.5, [234, 180, 0, 1]],
      [37.0, [235, 176, 0, 1]],
      [37.5, [236, 172, 0, 1]],
      [38.0, [237, 168, 0, 1]],
      [38.5, [238, 164, 0, 1]],
      [39.0, [239, 160, 0, 1]],
      [39.5, [240, 156, 0, 1]],
      [40.0, [255, 144, 0, 1]],
      [40.5, [246, 140, 0, 1]],
      [41.0, [247, 136, 0, 1]],
      [41.5, [248, 132, 0, 1]],
      [42.0, [249, 128, 0, 1]],
      [42.5, [250, 124, 0, 1]],
      [43.0, [251, 120, 0, 1]],
      [43.5, [252, 116, 0, 1]],
      [44.0, [253, 112, 0, 1]],
      [44.5, [255, 108, 0, 1]],
      [45.0, [255, 0, 0, 1]],
      [45.5, [253, 0, 0, 1]],
      [46.0, [251, 0, 0, 1]],
      [46.5, [249, 0, 0, 1]],
      [47.0, [247, 0, 0, 1]],
      [47.5, [245, 0, 0, 1]],
      [48.0, [243, 0, 0, 1]],
      [48.5, [241, 0, 0, 1]],
      [49.0, [239, 0, 0, 1]],
      [49.5, [237, 0, 0, 1]],
      [50.0, [214, 0, 0, 1]],
      [50.5, [212, 0, 0, 1]],
      [51.0, [210, 0, 0, 1]],
      [51.5, [208, 0, 0, 1]],
      [52.0, [206, 0, 0, 1]],
      [52.5, [204, 0, 0, 1]],
      [53.0, [202, 0, 0, 1]],
      [53.5, [200, 0, 0, 1]],
      [54.0, [198, 0, 0, 1]],
      [54.5, [196, 0, 0, 1]],
      [55.0, [192, 0, 0, 1]],
      [55.5, [190, 0, 0, 1]],
      [56.0, [188, 0, 0, 1]],
      [56.5, [186, 0, 0, 1]],
      [57.0, [184, 0, 0, 1]],
      [57.5, [182, 0, 0, 1]],
      [58.0, [180, 0, 0, 1]],
      [58.5, [178, 0, 0, 1]],
      [59.0, [176, 0, 0, 1]],
      [59.5, [174, 0, 0, 1]],
      [60.0, [255, 0, 240, 1]],
      [60.5, [247, 0, 234, 1]],
      [61.0, [239, 0, 228, 1]],
      [61.5, [231, 0, 222, 1]],
      [62.0, [223, 0, 216, 1]],
      [62.5, [215, 0, 210, 1]],
      [63.0, [207, 0, 204, 1]],
      [63.5, [199, 0, 198, 1]],
      [64.0, [191, 0, 192, 1]],
      [64.5, [183, 0, 186, 1]],
      [65.0, [150, 0, 180, 1]],
      [65.5, [152, 15, 186, 1]],
      [66.0, [154, 30, 192, 1]],
      [66.5, [156, 45, 198, 1]],
      [67.0, [158, 60, 204, 1]],
      [67.5, [160, 75, 210, 1]],
      [68.0, [162, 90, 216, 1]],
      [68.5, [164, 105, 222, 1]],
      [69.0, [167, 135, 228, 1]],
      [69.5, [170, 140, 234, 1]],
      [70.0, [173, 144, 240, 1]],
    ]

用法:

// 示例目标颜色
const targetColor = [1, 170, 245, 1]; // 某个颜色值

// 方法 1:直接找到最接近的数值
const closestValue = findValueFromColor(targetColor, colorRamp);
console.log('Closest value:', closestValue);

// 方法 2:通过插值找到更精确的数值
const interpolatedValue = findValueFromColorWithInterpolation(targetColor, colorRamp);
console.log('Interpolated value:', interpolatedValue);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值