ThreeJS创建三角带:网格遍历生成三角网格遇问题
解决基于窗口网格生成三角网格的问题
我懂你这种找不到适配方案的苦恼——虽然类似的网格生成问题有人问过,但每个人的场景细节不一样,适配起来确实麻烦。我结合你给出的代码片段,帮你梳理下三角网格生成的关键问题和调整方向:
先把你提到的核心代码片段贴出来方便分析:
const gridSize = 50; // 其他代码... var gridX = Math.ceil(windowX / gridSize); var gridY = Math.ceil(windowY / gridSize); // 渲染网格 for (var y = 0; y < gridY; y++) { var currentY ... }
一、先把网格节点的坐标精准落地
你现在的代码里只计算了网格的行列数,但要生成三角网格,首先得把每个网格节点的实际像素坐标存进数组里,而不只是记录索引:
// 初始化网格数组,存储每个节点的真实像素坐标 let grid = []; for (let y = 0; y <= gridY; y++) { let row = []; for (let x = 0; x <= gridX; x++) { row.push({ x: x * gridSize, y: y * gridSize }); } grid.push(row); }
这样后续生成三角时,直接取节点坐标就能避免偏移问题。
二、遍历网格拆分三角面
每个矩形网格单元都可以拆成两个三角形,这里推荐用交替拆分的方式,既能避免缝隙,还能让三角布局更自然:
// 遍历网格生成三角网格 for (let y = 0; y < gridY; y++) { for (let x = 0; x < gridX; x++) { // 取出当前网格单元的四个顶点 let topLeft = grid[y][x]; let topRight = grid[y][x+1]; let bottomLeft = grid[y+1][x]; let bottomRight = grid[y+1][x+1]; // 交替拆分方向:偶数列用一种拆分,奇数列换另一种 if (x % 2 === 0) { // 第一个三角:左上 → 右上 → 右下 drawTriangle(topLeft.x, topLeft.y, topRight.x, topRight.y, bottomRight.x, bottomRight.y); // 第二个三角:左上 → 右下 → 左下 drawTriangle(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y, bottomLeft.x, bottomLeft.y); } else { // 换方向避免重复规律 drawTriangle(topLeft.x, topLeft.y, bottomLeft.x, bottomLeft.y, topRight.x, topRight.y); drawTriangle(topRight.x, topRight.y, bottomLeft.x, bottomLeft.y, bottomRight.x, bottomRight.y); } } }
这里的drawTriangle需要你根据自己的渲染环境(比如Canvas、SVG)实现,核心是传入三个顶点的坐标进行绘制。
三、修正窗口边界的网格溢出问题
你用Math.ceil(windowX / gridSize)计算网格数,最后一行/列的网格可能会超出窗口范围,建议做个小修正:
// 先取整数倍的网格数 gridX = Math.floor(windowX / gridSize); gridY = Math.floor(windowY / gridSize); // 如果窗口尺寸不是gridSize的整数倍,补一个小网格到边缘 const extraX = windowX % gridSize; const extraY = windowY % gridSize; if (extraX > 0) gridX++; if (extraY > 0) gridY++;
这样既能铺满整个窗口,又不会出现超出可视区域的网格。
如果你还有具体的渲染异常(比如三角重叠、缝隙),可以补充下drawTriangle的实现细节,我再帮你调整~
内容的提问来源于stack exchange,提问作者Norman
相关产品推荐
相关产品推荐

