You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Voronoi图中平滑插值颜色以消除单元格边界?

消除Voronoi图单元格边界并实现颜色平滑插值的方案

你当前的Voronoi图存在可见单元格边界,原因是每个像素的颜色仅由最近的单个控制点决定,即使做了距离插值,也只是向单一方向过渡,单元格间的颜色衔接会产生突变。要实现平滑的跨单元格颜色插值,需要让每个像素的颜色由多个邻近控制点的颜色加权混合而成,而不是只依赖最近点。

当前Voronoi图存在可见边界

修改思路

  • 计算当前像素到所有控制点的带噪声扭曲距离
  • 基于距离生成平滑衰减的权重(距离越近,权重越高)
  • 用所有权重对对应控制点的颜色进行加权平均,得到当前像素的最终颜色

修改后的代码

function drawVoronoiNoise(canvas, cells = 50, noiseScale = 0.06, distortionStrength = 5) {
  const ctx = canvas.getContext('2d');
  const controlPoints = [];

  // 生成带随机灰度颜色的控制点
  for (let i = 0; i < cells; i++) {
    const x = seededRandom(i) * canvas.width;
    const y = seededRandom(i + 1) * canvas.height;
    const grayValue = noise(x / 188.05, y / 188.05) * 255;
    controlPoints.push({ x, y, color: { r: grayValue, g: grayValue, b: grayValue } });
  }

  // 遍历画布每个像素
  for (let x = 0; x < canvas.width; x++) {
    for (let y = 0; y < canvas.height; y++) {
      let totalWeight = 0;
      let finalColor = { r: 0, g: 0, b: 0 };
      const epsilon = 0.1; // 避免除以0

      for (const cp of controlPoints) {
        // 带噪声扭曲的距离计算
        const noiseX = noise(x * noiseScale, y * noiseScale) * distortionStrength;
        const noiseY = noise(x * noiseScale + 100, y * noiseScale + 100) * distortionStrength;
        const distance = Math.hypot(x - cp.x + noiseX, y - cp.y + noiseY);

        // 使用平滑衰减的权重(这里用距离倒数的平方,衰减更自然)
        const weight = 1 / (distance * distance + epsilon);
        totalWeight += weight;

        // 累加颜色权重
        finalColor.r += cp.color.r * weight;
        finalColor.g += cp.color.g * weight;
        finalColor.b += cp.color.b * weight;
      }

      // 归一化得到最终颜色
      finalColor.r = Math.round(finalColor.r / totalWeight);
      finalColor.g = Math.round(finalColor.g / totalWeight);
      finalColor.b = Math.round(finalColor.b / totalWeight);

      ctx.fillStyle = `rgb(${finalColor.r}, ${finalColor.g}, ${finalColor.b})`;
      ctx.fillRect(x, y, 1, 1);
    }
  }
}

关键改动说明

  • 权重计算:使用1/(distance² + epsilon)作为权重,距离控制点越近的像素,该控制点对其颜色的影响越大,且权重平滑衰减,避免突变
  • 多控制点混合:每个像素的颜色是所有控制点颜色的加权平均,单元格边界附近的像素会同时受到相邻多个控制点的影响,自然消除硬边界
  • 灵活调整过渡效果:如果需要更柔和的过渡,可以改用高斯函数Math.exp(-distance² / (2 * sigma²))作为权重;想要稍锐利的过渡,可改用1/(distance + epsilon)计算权重

内容的提问来源于stack exchange,提问作者Memory1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:16:14