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

如何修改Tess2或使用其他JavaScript库在轮廓三角化生成2D网格时保留颜色数据

解决三角化三角形保留颜色数据的两种思路

我之前做2D图形渲染的时候也碰到过完全一样的需求,给你分享两种可行的方案:一种是修改Tess2源码来实现颜色关联,另一种是用现成的库直接搞定。

一、修改Tess2源码关联颜色数据

Tess2本身没设计颜色关联的逻辑,但它的源码结构很清晰,我们可以给轮廓和最终的三角形加上颜色属性:

1. 扩展轮廓输入结构

原来你传入的轮廓大概是这样的:

const contours = [
  { vertices: [x1, y1, x2, y2, ...], winding: Tess2.WINDING_NEGATIVE }, // 实心区域
  { vertices: [x3, y3, x4, y4, ...], winding: Tess2.WINDING_POSITIVE }  // 孔洞
];

现在给每个实心轮廓(注意孔洞不需要颜色)加上color字段:

const contours = [
  { vertices: [x1, y1, x2, y2, ...], winding: Tess2.WINDING_NEGATIVE, color: '#ff0000' },
  { vertices: [x3, y3, x4, y4, ...], winding: Tess2.WINDING_POSITIVE }
];

2. 在Tess2中保存轮廓颜色

找到Tess2源码里的addContour方法(大概在Tesselator类里),修改它的逻辑,把传入的color参数存储到对应的轮廓对象中。比如:

// 原addContour方法可能接收vertices和winding,现在改成接收完整的轮廓对象
addContour(contour) {
  const { vertices, winding, color } = contour;
  // 保留原有的顶点、缠绕顺序处理逻辑
  // 新增:保存颜色到轮廓数据里
  this.contours.push({ vertices, winding, color });
}

3. 给生成的三角形绑定颜色

Tess2最终会生成包含三角形顶点索引的meshes数据。你需要找到源码中构建三角形的部分(比如generateMesh相关逻辑),这里需要跟踪每个三角形所属的实心轮廓。

因为Tess2是根据缠绕顺序区分实心和孔洞的,每个最终的填充三角形必然属于某个WINDING_NEGATIVE的轮廓。如果源码里直接找不到面和轮廓的关联,也可以用简化方法:对每个实心轮廓单独调用Tess2三角化,然后给这个轮廓生成的所有三角形统一赋予该轮廓的颜色。这种方法适合没有重叠布尔运算的场景,实现起来更简单。

二、用现成库直接实现:Earcut + 自定义颜色映射

如果不想改源码,推荐用earcut这个轻量的三角化库,它支持带孔洞的多边形,而且很容易给三角形绑定颜色:

1. 按区域组织轮廓

把每个带颜色的实心轮廓(以及对应的孔洞)作为一个独立的区域,比如:

const regions = [
  {
    color: '#ff0000',
    outer: [x1, y1, x2, y2, ...], // 实心轮廓点
    holes: [[x3, y3, x4, y4, ...]] // 该区域的孔洞
  },
  {
    color: '#00ff00',
    outer: [x5, y5, x6, y6, ...],
    holes: []
  }
];

2. 逐个区域三角化并绑定颜色

对每个区域,用earcut生成三角化索引,然后给每个三角形赋予该区域的颜色:

import earcut from 'earcut';

const coloredTriangles = [];

regions.forEach(region => {
  // 构造earcut需要的输入格式:顶点数组 + 孔洞索引数组
  const vertices = [...region.outer];
  const holeIndices = region.holes.map(hole => vertices.length);
  region.holes.forEach(hole => vertices.push(...hole));
  
  // 生成三角化索引
  const indices = earcut(vertices, holeIndices);
  
  // 把索引转换成三角形,并绑定颜色
  for (let i = 0; i < indices.length; i += 3) {
    coloredTriangles.push({
      color: region.color,
      vertices: [
        [vertices[indices[i]*2], vertices[indices[i]*2+1]],
        [vertices[indices[i+1]*2], vertices[indices[i+1]*2+1]],
        [vertices[indices[i+2]*2], vertices[indices[i+2]*2+1]]
      ]
    });
  }
});

这样生成的coloredTriangles数组里,每个三角形都带着对应的颜色数据,完全满足你的需求。

补充说明

如果你需要处理复杂的布尔运算(比如多个轮廓重叠后的混合颜色),那可能需要在三角化后额外做区域检测,但大部分场景下,上面两种方法足够解决问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:24:06