代码之家  ›  专栏  ›  技术社区  ›  Michal

在THREE.js中为螺旋星系生成粒子

  •  0
  • Michal  · 技术社区  · 7 年前

    我想创建一个简单的螺旋星系使用 THREE.Points 在e.js。

    fiddle . 有一个扁平的球体,但没有旋臂。

    const scene = new THREE.Scene()
    const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight)
    camera.position.z = 1500
    scene.add(camera)
    const renderer = new THREE.WebGLRenderer({ clearColor: 0x000000 })
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)
    
    // Random function with normal dustribution.
    const normalRandom = (mean, std) => {
        let n = 0
        
        for (let i = 1; i <= 12; i++) {
          n += Math.random()
        }
    
        return (n - 6) * std + mean
    }
    
    const geometry = new THREE.Geometry()
    const galaxySize = 1000
    
    // Generate particles for spiral galaxy:
    for (let i = 0; i < 10000; i++) {
      var theta = THREE.Math.randFloatSpread(360) 
      var phi = THREE.Math.randFloatSpread(360)
      const distance = THREE.Math.randFloatSpread(galaxySize)
    
      // Here I need to generate spiral arms instead of a sphere.
      geometry.vertices.push(new THREE.Vector3(
      	 distance * Math.sin(theta) * Math.cos(phi),
         distance * Math.sin(theta) * Math.sin(phi),
         distance * Math.cos(theta) / 10
      ))
    }
    
    const spiralGalaxy = new THREE.Points(geometry, new THREE.PointsMaterial({ color: 0xffffff }))
    scene.add(spiralGalaxy)
    
    function render() {
        requestAnimationFrame(render)
        renderer.render(scene, camera)
        spiralGalaxy.rotation.x += 0.01;
        spiralGalaxy.rotation.y += 0.01;
    }
    
    render()
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script>
    0 回复  |  直到 7 年前
        1
  •  5
  •   M -    7 年前

    看起来你已经用极坐标系做了很多繁重的工作。但是,请记住,角度是以弧度为单位的,而不是以度为单位的,因此不要使用 360 ,您应该使用 PI * 2 . 现在你要做的就是两者都增加 distance theta 同时创造一个螺旋,而 phi

    • 距离 将从 0 galaxySize
    • 将从 0 Math.PI (或 π*2 ,如果您想要更紧密的螺旋)
    • 保持接近0
    // Temp variables to assign new values inside loop
    var norm, theta, phi, thetaVar, distance;
    
    // Generate particles for spiral galaxy:
    for (let i = 0; i < 1000; i++) {
        // Norm increments from 0 to 1
        norm = i / 1000;
    
        // Random variation to theta [-0.5, 0.5]
        thetaVar = THREE.Math.randFloatSpread(0.5);
    
        // Theta grows from 0 to Math.PI (+ random variation)
        theta = norm * Math.PI + thetaVar;
    
        // Phi stays close to 0 to create galaxy ecliptic plane
        phi = THREE.Math.randFloatSpread(0.1);
    
        // Distance grows from 0 to galaxySize
        distance = norm * galaxySize;
    
        // Here I need generate spiral arms instead of sphere.
        geometry.vertices.push(new THREE.Vector3(
            distance * Math.sin(theta) * Math.cos(phi),
            distance * Math.sin(theta) * Math.sin(phi),
            distance * Math.cos(theta)
        ));
    }
    

    你可以为每只手臂创建一个环。请注意,我没有像您在示例中那样在末尾除以10,而是将phi的范围限制为 [-0.1, 0.1] in this fiddle