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

如何用Three.js生成由独立网格组成的90度分段圆环?

用Three.js生成独立网格组成的90度分段圆环

ShapeGeometry方案完全可行,下面是具体实现思路和代码:

实现思路

要生成独立的90度分段圆环,核心是为每个分段创建扇形环形的2D路径,再通过ShapeGeometry转换成网格。关键在于准确计算每个分段的角度范围,以及正确绘制环形路径的内外圆弧。

步骤拆解:

  1. 计算每个分段的有效角度:总角度为90°(Math.PI/2弧度),减去所有网格间的间距总和后,平均分配给每个网格。
  2. 为每个分段绘制扇形环形路径:由外圆弧、内圆弧和两条连接直线组成闭合形状。
  3. 将每个路径转换成独立网格,添加到场景中。

完整代码实现

// 基础场景设置
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 50;

// 生成分段圆环的核心函数
function generateSegmentedTorus(innerRadius, thickness, count, padding) {
    const totalAngle = Math.PI / 2; // 90度对应的弧度
    // 计算每个分段的角度(减去所有间距后的平均角度)
    const anglePerSegment = (totalAngle - count * padding) / count;
    
    for (let i = 0; i < count; i++) {
        // 计算当前分段的起始和结束角度
        const startAngle = i * (anglePerSegment + padding);
        const endAngle = startAngle + anglePerSegment;
        
        // 创建扇形环形的Shape路径
        const segmentShape = new THREE.Shape();
        const outerRadius = innerRadius + thickness;
        
        // 移动到外圆弧起点
        const outerStart = new THREE.Vector2(
            outerRadius * Math.cos(startAngle),
            outerRadius * Math.sin(startAngle)
        );
        segmentShape.moveTo(outerStart.x, outerStart.y);
        
        // 绘制外圆弧
        segmentShape.absarc(0, 0, outerRadius, startAngle, endAngle, false);
        
        // 直线连接到内圆弧终点
        const innerEnd = new THREE.Vector2(
            innerRadius * Math.cos(endAngle),
            innerRadius * Math.sin(endAngle)
        );
        segmentShape.lineTo(innerEnd.x, innerEnd.y);
        
        // 反向绘制内圆弧,形成闭合路径
        segmentShape.absarc(0, 0, innerRadius, endAngle, startAngle, true);
        
        // 直线回到起点,完成闭合
        segmentShape.lineTo(outerStart.x, outerStart.y);
        
        // 创建网格并添加到场景
        const geometry = new THREE.ShapeGeometry(segmentShape);
        // 用随机颜色区分不同网格
        const material = new THREE.MeshBasicMaterial({ 
            color: new THREE.Color().setHSL(i/count, 0.8, 0.6),
            wireframe: false // 改为true可查看路径结构
        });
        const segmentMesh = new THREE.Mesh(geometry, material);
        
        // 如需3D立体效果,替换为ExtrudeGeometry:
        // const extrudeSettings = { depth: 1, bevelEnabled: false };
        // const geometry = new THREE.ExtrudeGeometry(segmentShape, extrudeSettings);
        
        scene.add(segmentMesh);
    }
}

// 调用示例:内半径10,厚度3,4个分段,每个分段间距0.1弧度(约5.7°)
generateSegmentedTorus(10, 3, 4, 0.1);

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();

参数说明

  • innerRadius:圆环的内半径(从中心到环形内侧的距离)
  • thickness:圆环的径向厚度(环形外侧与内侧的半径差)
  • count:独立网格的数量
  • padding:每个网格之间的间距(单位:弧度,例如0.1≈5.7°)

关键细节

  • 使用absarc绘制圆弧时,最后一个参数控制绘制方向:外圆弧用false(顺时针),内圆弧用true(逆时针),确保路径闭合正确。
  • 每个网格都是独立的Mesh实例,支持单独修改材质、位置或旋转。
  • 如果需要立体的环形分段,只需将ShapeGeometry替换为ExtrudeGeometry,并设置depth参数控制立体厚度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:45:30