Three.js 创建 n 个网格以形成光滑的 90 度甜甜圈

问题描述 投票:0回答:1

我正在尝试找到一种算法来在 Three.js 中生成以下内容。 Expected outcome (Pardon my drawing skills) 形成 90 度甜甜圈的网格数量、厚度和它们之间的填充应该是可变的。

我知道您可以使用 TorusGeometry 将径向线段设置为 2 并沿着以下线减少圆弧来创建类似的东西:

const geometry = new THREE.TorusGeometry( 10, 3, 2, 100 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const torus = new THREE.Mesh( geometry, material );
scene.add( torus );

但这不起作用,因为正如我预期的结果所示,我需要单独的网格。所以我进一步研究并遇到了ShapeGeometry。我认为要走的路是使用 ShapeGeometry。

const generateArc = (padding, thickness, count) => {
     const arcShape = new THREE.Shape()
        .moveTo( 50, 10 )
        .absarc( 10, 10, 40, 0, Math.PI * 2, false );
}

但我无法弄清楚如何进行正确的数学计算来生成这些单独的网格弧。 我使用 ShapeGeometry 的方法是否正确?如果是这样,我如何使用形状几何体生成正确的网格。

javascript three.js geometry shapes mesh
1个回答
1
投票

不要忘记

TorusGeometry
构造函数中的第5个参数是圆弧,看起来你没有使用它。

TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)

通过使用此弧,您可以制作一个 90 度的分数的环面。它以弧度为单位测量,因此要在 90 度内获得 3 段,它需要是

(Math.PI / 2) / 3
Math.PI / 6
。请参阅下面的工作示例:

var camera, scene, renderer;

init();
render();

function init() {
    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 50 );
    camera.position.set( 0, 0, 15 );

    scene = new THREE.Scene();
    const MARGIN = Math.PI / 100;
    
    var torusArc = Math.PI / 6 - MARGIN;
    var geometry = new THREE.TorusGeometry( 5, 1, 16, 32, torusArc);
    
    var material = new THREE.MeshNormalMaterial({side: THREE.DoubleSide});

    var mesh1 = new THREE.Mesh( geometry, material );
    var mesh2 = new THREE.Mesh( geometry, material );
    mesh2.rotation.z = Math.PI / 6 + MARGIN;
    var mesh3 = new THREE.Mesh( geometry, material );
    mesh3.rotation.z = (Math.PI / 6 + MARGIN) * 2;

    scene.add( mesh1 );
    scene.add( mesh2 );
    scene.add( mesh3 );

    renderer = new THREE.WebGLRenderer( { antialias: false } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    new THREE.OrbitControls( camera, renderer.domElement );

    window.addEventListener( 'resize', onWindowResize, false );
}

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );
}


function render(time) {
    camera.positi
    renderer.render( scene, camera );
    requestAnimationFrame( render );
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.