土星环 - 初始条件

时间:2018-06-05 17:14:57

标签: javascript three.js physics

我正在研究土星系统的模拟,这将允许用户,例如,将其最大的月亮泰坦的质量增加到地球的质量,并看看其他卫星和环如何被扰乱为结果。我对环的表示是一个粗粒子系统,其中每个粒子都以一组x,y,z位置和速度向量开始。如果我将z位置和速度矢量设置为0,我会得到一个相当漂亮的环绕土星旋转,但问题是土星的轴向倾斜(其旋转轴倾斜到其轨道平面)为27度所以你必须考虑到z位置和速度向量才能使模拟至少在某种程度上是现实的,但经过大量的呻吟和呻吟之后,我还没有能够正确地获得环的倾斜度。 / p>

这是为构成环的粒子创建初始条件的方法:

init() {

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

    const rad = Math.PI * 2 * Math.random();
    const dist = (25 + 20 * Math.random()) / 32000;

    this.particles.push({
      x: Math.cos(rad) * dist,
      y: Math.sin(rad) * dist,
      z: 0,
      vx: (Math.cos(rad + Math.PI / 2 + (Math.PI / 180 * 6 - Math.PI / 180 * 12) * 0) * Math.sqrt(500 / dist)) / 120,
      vy: (Math.sin(rad + Math.PI / 2 + (Math.PI / 180 * 6 - Math.PI / 180 * 12) * 0) * Math.sqrt(500 / dist)) / 120,
      vz: 0
    });

  }

}

有没有人可以帮我弄清楚如何根据上面的代码获得z位置和速度向量?如上所述,轴向倾斜应为27度。

1 个答案:

答案 0 :(得分:2)

只是一个如何做到这一点的概念:

&#13;
&#13;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 10, 20);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setClearColor(0x101010);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var sun = new THREE.Mesh(new THREE.SphereGeometry(2, 16, 8), new THREE.MeshBasicMaterial({
  color: "orange"
}));
scene.add(sun);

var orbitGeom = new THREE.CircleGeometry(10, 32);
orbitGeom.rotateX(-Math.PI * 0.5);
orbitGeom.vertices.shift();
var orbit = new THREE.LineLoop(orbitGeom, new THREE.LineBasicMaterial({
  color: "yellow"
}));
scene.add(orbit);

var saturnSys = new THREE.Group();
var saturnSysAxis = new THREE.Vector3(0, 1, 0);
saturnSys.rotation.z = THREE.Math.degToRad(27);
saturnSys.add(new THREE.AxesHelper(5));
var saturnPlanet = new THREE.Mesh(new THREE.SphereGeometry(1, 8, 6), new THREE.MeshBasicMaterial({
  color: 0xFACE8D,
  wireframe: true
}));
saturnSys.add(saturnPlanet);

var saturnRingGeom = new THREE.Geometry();
var vertices = [];
for (let i = 0; i < 2000; i++) {
  let r = THREE.Math.randFloat(1.5, 4);
  let angle = THREE.Math.randFloat(0, Math.PI * 2);
  let v = new THREE.Vector3(
    Math.cos(angle) * r,
    0,
    Math.sin(angle) * r
  );
  v.angularVelocity = THREE.Math.randFloat(0.1, Math.PI);
  vertices.push(v);
}

saturnRingGeom.vertices = vertices;

var saturnRing = new THREE.Points(saturnRingGeom, new THREE.PointsMaterial({
  size: 0.1,
  color: "red"
}));
saturnSys.add(saturnRing);

scene.add(saturnSys);

var clock = new THREE.Clock();
var time = 0;
var delta = 0;

render();

function render() {
  requestAnimationFrame(render);
  delta = clock.getDelta();
  time += delta * 0.1;
  saturnSys.position.set(
    Math.cos(time) * 10,
    0,
    Math.sin(time) * 10
  );
  saturnPlanet.rotation.y = time * 3;
  saturnRing.geometry.vertices.forEach(v => {
    v.applyAxisAngle(saturnSysAxis, v.angularVelocity * delta);
  });
  saturnRing.geometry.verticesNeedUpdate = true;
  renderer.render(scene, camera);
}
&#13;
body {
  overflow: hidden;
  margin: 0;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.min.js"></script>
&#13;
&#13;
&#13;