Кольца Сатурна - начальные условия - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над моделированием системы Сатурна, которая позволит пользователю, например, увеличить массу своего самого большого Лунного Титана до массы Земли и посмотреть, как в результате этого возмущаются другие луны и кольца.Мое представление о кольцах представляет собой грубую систему частиц, где каждая частица начинается с набора векторов положения x, y, z и скорости.Если я установлю z и векторы скорости на 0, я получу довольно красивое кольцо, которое вращается вокруг Сатурна, но проблема в том, что Сатурн имеет осевой наклон (наклон его оси вращения к своей плоскости орбиты) 27 градусовпоэтому вы должны принять во внимание векторы положения и скорости z, чтобы симуляция была хотя бы несколько реалистичной, но после многих стонов и стонов я не смог правильно определить наклон колец.

Это метод, который создает начальные условия для частиц, составляющих кольцо:

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 голосов
/ 05 июня 2018

Просто представление о том, как вы можете это сделать:

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);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.min.js"></script>
...