简体   繁体   English

在THREE.js中生成旋涡星系的粒子

[英]Generate particles for spiral galaxy in THREE.js

I would like to create a simple spiral galaxy using THREE.Points in THEE.js. 我想使用THREE.Points中的THREE.Points创建一个简单的螺旋星系。
I cannot figure out how to generate spiral arms. 我不知道如何产生螺旋臂。 Is there any (not too difficult) way to do this? 有什么(不太困难)的方法吗?

Here I created this fiddle . 在这里,我创建了这个小提琴 There is a flattened sphere but without spiral arms. 有一个扁平的球体,但没有螺旋臂。

 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> 

Looks like you've already done a lot of the heavy lifting yourself, with the polar coordinate system. 看起来您已经使用极坐标系完成了许多繁重的工作。 Keep in mind, however, that the angles are in radians, not in degrees, so instead of using 360 , you should be using PI * 2 . 但是请记住,角度以弧度为单位,而不是以度为单位,因此,应使用PI * 2而不是360 Now all you have to do is increment both distance and theta simultaneously to create a spiral, while phi remains close to 0 to create the galaxy's ecliptic plane. 现在,您要做的就是同时增加distancetheta以创建螺旋,而phi保持接近0以创建星系的黄道面。

  • distance will grow from 0 to galaxySize distance将从0增加到galaxySize
  • theta will grow from 0 to Math.PI (or PI * 2 , if you want tighter spirals) theta将从0增加到Math.PI (如果需要更紧密的螺旋,则为PI * 2
  • phi stays close to 0 phi保持接近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)
    ));
}

You could create one loop for each arm. 您可以为每个手臂创建一个循环。 Notice that instead of dividing by 10 at the end, as you did in your example, I simply limited the range of phi to [-0.1, 0.1] . 注意,不是像您在示例中那样最后除以10,我只是将phi的范围限制为[-0.1, 0.1] You can see it in action in this fiddle 您可以在这个小提琴中看到它的实际作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM