三.JS - 粒子在随机方向上绕一个点形成一个球体 [英] Three.JS - Particles orbiting a point in random directions forming a sphere
问题描述
我有一个粒子系统,其中所有粒子都位于相同的坐标处,并且一个接一个地,在随机方向上,它们(应该)开始围绕场景的中心运行,形成一个球体.
I have a particle system where all the particles are positioned at the same coordinates and one after another, in random directions, they (should) start orbiting the center of the scene forming a sphere.
到目前为止,我设法实现的是一组 Vector3 对象(粒子),它们一个接一个地开始沿着 Z 轴围绕中心运行,只是根据当前角度计算它们的正弦和余弦.
What I managed to achieve until now is a group of Vector3 objects (the particles) that one after another start orbiting the center along the Z axis simply calculating their sine and cosine based on the current angle.
我的数学不太好,我什至不知道要准确地寻找什么.
I'm not that good at math and I don't even know what to look for precisely.
这是我写的:
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/
And here's the JSFiddle if you want to see it live: https://jsfiddle.net/kekkorider/qs6s0wv2/
编辑:工作示例
有人可以帮我吗?
提前致谢!
推荐答案
您希望每个粒子围绕特定的随机轴旋转.您可以让他们遵循圆的参数方程 在 3D 空间中,或者您可以使用 THREE.js 旋转矩阵.
You want each particle to rotate around a specific random axis. You can either let them follow a parametric equation of a circle in 3D space, or you can make use of THREE.js rotation matrices.
现在您所有的粒子都围绕矢量 (0, 0, 1) 旋转.由于您的粒子从 x 轴开始,您希望它们都围绕 y-z 平面 (0, y, z) 中的随机向量旋转.这可以在创建顶点期间定义:
Right now all your particles are rotating round the vector (0, 0, 1). Since your particles start off on the x-axis, you want them all to rotate around a random vector in the y-z plane (0, y, z). This can be defined during the creation of the vertices:
vertex.rotationAxis = new THREE.Vector3(0, Math.random() * 2 - 1, Math.random() * 2 - 1);
vertex.rotationAxis.normalize();
现在您可以使用每次更新创建的随机旋转轴在每个粒子上调用 THREE.Vector3.applyAxisAngle(axis, angle)
方法:
now you can just call the THREE.Vector3.applyAxisAngle(axis, angle)
method on each of your particles with the random rotation axis you created each update:
particle.applyAxisAngle(particle.rotationAxis, 0.01);
总而言之,它应该是这样的:
To sum up, this is how it should look like:
draw():
...
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);
}
}
...
这篇关于三.JS - 粒子在随机方向上绕一个点形成一个球体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!