2017-04-18 74 views
2

我有一個粒子系統,其中所有的粒子都位於相同的座標和一個接着一個,在隨機的方向,他們(應)開始軌道的中心現場形成一個球體。three.js所 - 粒子軌道在任意方向的點形成一個球體

我到目前爲止設法實現的是一組Vector3對象(粒子),它們沿着Z軸開始繞中心運動,根據當前角度簡單計算它們的正弦和餘弦。

我不是那種擅長數學,我甚至不知道要尋找什麼精確。

這是我寫的:

var scene = new THREE.Scene(); 

let container = document.getElementById('container'), 
    loader = new THREE.TextureLoader(), 
    renderer, 
    camera, 
    maxParticles = 5000, 
    particlesDelay = 50, 
    radius = 50, 
    sphereGeometry, 
    sphere; 

loader.crossOrigin = true; 

function init() { 

    let vw = window.innerWidth, 
     vh = window.innerHeight; 

    renderer = new THREE.WebGLRenderer(); 
    renderer.setSize(vw, vh); 
    renderer.setPixelRatio(window.devicePixelRatio); 

    camera = new THREE.PerspectiveCamera(45, vw/vh, 1, 1000); 
    camera.position.z = 200; 
    camera.position.x = 30; 
    camera.position.y = 30; 
    camera.lookAt(scene.position); 
    scene.add(camera); 

    let controls = new THREE.OrbitControls(camera, renderer.domElement); 

    let axisHelper = new THREE.AxisHelper(50); 
    scene.add(axisHelper); 

    container.appendChild(renderer.domElement); 

    window.addEventListener('resize', onResize, false); 

} 

function onResize() { 

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

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

} 

function draw() { 

    sphereGeometry = new THREE.Geometry(); 
    sphereGeometry.dynamic = true; 

    let particleTexture = loader.load('https://threejs.org/examples/textures/particle2.png'), 
     material = new THREE.PointsMaterial({ 
      color: 0xffffff, 
      size: 3, 
      transparent: true, 
      blending: THREE.AdditiveBlending, 
      map: particleTexture, 
      depthWrite: false 
     }); 

     for (let i = 0; i < maxParticles; i++) { 

      let vertex = new THREE.Vector3(radius, 0, 0); 
      vertex.delay = Date.now() + (particlesDelay * i); 
      vertex.angle = 0; 
      sphereGeometry.vertices.push(vertex); 

     } 

     sphere = new THREE.Points(sphereGeometry, material); 
     scene.add(sphere); 

} 

function update() { 

    for (let i = 0; i < maxParticles; i++) { 

     let particle = sphereGeometry.vertices[i]; 

     if (Date.now() > particle.delay) { 

      let angle = particle.angle += 0.01; 

      particle.x = radius * Math.cos(angle); 

      if (i % 2 === 0) { 
       particle.y = radius * Math.sin(angle); 
      } else { 
       particle.y = -radius * Math.sin(angle); 
      } 

     } 


    } 

    sphere.geometry.verticesNeedUpdate = true; 

} 

function render() { 

    update(); 
    renderer.render(scene, camera); 
    requestAnimationFrame(render); 

} 

init(); 
draw(); 
render(); 

而這裏的的jsfiddle如果你想現場觀看: https://jsfiddle.net/kekkorider/qs6s0wv2/

編輯Working example

可有人請給我一個手?

在此先感謝!

回答

3

您希望每個粒子圍繞特定的隨機軸旋轉。您可以讓他們在3D空間中跟隨parametric equation of a circle,也可以使用THREE.js旋轉矩陣。

現在所有的粒子都圍繞向量旋轉(0,0,1)。由於您的粒子在x軸上開始,因此您希望它們都圍繞y-z平面(0,y,z)中的隨機向量旋轉。這可以創造頂點的過程中被定義爲:

vertex.rotationAxis = new THREE.Vector3(0, Math.random() * 2 - 1, Math.random() * 2 - 1); 
vertex.rotationAxis.normalize(); 

現在你可以調用每個與隨機旋轉的顆粒THREE.Vector3.applyAxisAngle(axis, angle)方法軸您創建的每個更新:

particle.applyAxisAngle(particle.rotationAxis, 0.01); 

綜上所述起來,這是應該的樣子:

平局()

... 
for (let i = 0; i < maxParticles; i++) { 

    let vertex = new THREE.Vector3(radius, 0, 0); 
    vertex.delay = Date.now() + (particlesDelay * i); 
    vertex.rotationAxis = new THREE.Vector3(0, Math.random() * 2 - 1, Math.random() * 2 - 1); 
    vertex.rotationAxis.normalize(); 
    sphereGeometry.vertices.push(vertex); 
} 
... 

更新()

... 
for (let i = 0; i < maxParticles; i++) { 

    let particle = sphereGeometry.vertices[i]; 

    if (Date.now() > particle.delay) { 
     particle.applyAxisAngle(particle.rotationAxis, 0.01); 
    } 
} 
... 
+1

嗨@micnil,您的解決方案做過的魅力,非常感謝您的幫助:) 我添加了一個鏈接到一個工作示例的情況下,其他人需要它。 –

+0

@micnil你能爲我澄清一些事嗎?我一直在研究這個例子,因爲它產生了非常酷的效果,並且我計劃構建一個「黑洞」場景。 'vertex.rotationAxis',它是一個具有隨機y和z值的Vector3,如何使粒子在隨機方向上旋轉?我一直在jsfiddle上玩了​​幾天,我仍然不明白是什麼造成了粒子形成球體的這種效應。我發現'applyAxisAngle'就是創造這個的魔法,但是,我不明白爲什麼要爲每個粒子的'rotationAxis'調整y和z來做到這一點。 –

+1

@AlexFallenstedt基本上我創建了一個粒子可以旋轉的矢量。在沒有圖像和數字的評論中,在文本中解釋有點困難。但請考慮你的小提琴的這個版本:[https:// jsfiddle。淨/ qs6s0wv2/5 /(https://jsfiddle.net/qs6s0wv2/5/)。嘗試按下「運行」一段時間的聯接,您將看到粒子在其旋轉軸改變時的行爲。 – micnil