【问题标题】:Rotating Earth around Sun地球绕太阳旋转
【发布时间】:2014-02-02 22:42:01
【问题描述】:

我正在尝试制作 3D 太阳系,所以首先我使用 THREE.SphereGeometry() 创建了太阳和地球

var sphere2 = new THREE.Mesh(new THREE.SphereGeometry(50, 100, 100),
new THREE.MeshBasicMaterial({side: THREE.DoubleSide, map:txt2}));
sphere2.position.set(100,5,30);

sphere2 是地球,我想围绕太阳旋转它,在我的render() 中添加了

  sphere2.position.x -= 1;
  sphere2.position.normalize();
  sphere2.position.multiplyScalar( 200 );

我想我只需要编辑x轴的位置,对吧?但据我所见,这只旋转了一半。我显然需要在一段时间后停止减法并增加x位置,但这只会使地球向后退,它不会落后于太阳,它总是绕半圈然后停止,最后x位置的值为“ -200” 我期待找到它“-100”,但不知道为什么。我还想给地球一个 23.5 度的轴向倾斜,我尝试使用 quaternion = new THREE.Quaternion().setFromAxisAngle( axisOfRotation, angleOfRotation ); 但没有奏效。如果你能帮我一把,我会很高兴!

【问题讨论】:

  • “我想我只需要编辑 x 轴的位置,对吧?” 我觉得这行不通。在某些时候,地球的位置将位于 x 轴的顶部,此时减去 1 并归一化根本不会改变它的位置。您应该考虑提出不同的策略。

标签: javascript html math three.js


【解决方案1】:

最简单(虽然在科学上不准确)的做法是将 Math.cos/sin 与更新角度值配对使用。框架更新中的类似内容:

earthOrbitAngle += earthOrbitSpeed; //advance angle in degrees
var orbitAngleInRadians = earthOrbitAngle * Math.PI / 180; //convert to radians

//update position of earth...
earth.position.x = Math.cos(orbitAngleInRadians) * earthOrbitRadius; 
earth.position.z = Math.sin(orbitAngleInRadians) * earthOrbitRadius;

您可以通过将 earthOrbitRadius 乘以某个因子来拉长 x 或 z 值以使轨道呈椭圆形。

你可以通过设置它的 rotation.z 来倾斜地球。但是,如果您想让月球绕倾斜轴运行,那么最简单的方法是创建一个空的 Object3D 容器来容纳这两个容器,并让月球运行自己的轨道运行脚本。然后,您围绕太阳为该容器设置动画。所以设置看起来像这样:

theSun = new THREE.Mesh(new THREE.SphereGeometry(30, 16, 15), new THREE.MeshBasicMaterial({
    color: 'yellow' 
}));
scene.add(theSun);

theEarthAndMoon = new THREE.Object3D();
theEarthAndMoon.rotation.z = 23.439281 * Math.PI / 180; //tilt of earth in radians;
scene.add(theEarthAndMoon);

theEarth = new THREE.Mesh(new THREE.SphereGeometry(5, 16, 15),  new THREE.MeshLambertMaterial({
    color:"blue"
}));

theEarthAndMoon.add(theEarth); 

theMoon = new THREE.Mesh(new THREE.SphereGeometry(1, 16, 15),  new THREE.MeshLambertMaterial({
    color:"white"
}));

theEarthAndMoon.add(theMoon);

在帧更新中:

//run the earth's orbit around the Sun
earthOrbitAngle += earthOrbitSpeed; 
var radians = earthOrbitAngle * Math.PI / 180;

theEarthAndMoon.position.x = Math.cos(radians) * earthOrbitRadius;
theEarthAndMoon.position.z = Math.sin(radians) * earthOrbitRadius;

//run the Moon's orbit around the Earth
moonOrbitAngle += moonOrbitSpeed; 
var moonRadians = moonOrbitAngle * Math.PI / 180;

theMoon.position.x = Math.cos(moonRadians) * moonOrbitRadius;
theMoon.position.z = Math.sin(moonRadians) * moonOrbitRadius;

你可以看到它在这里运行:Simple Sun, Earth, and Moon at JSFiddle

现在,如果您想深入了解精确轨道力学的兔子洞,我建议您从查看这个令人难以置信的 Three.js 模拟所有行星和 600,000 颗小行星的引擎盖开始:Asterank project

【讨论】:

  • 亲爱的 Matthew 我非常感谢您付出了很多努力并提供了正确的解决方案,我希望您早一点出现 :) 但是我很高兴您开始回答问题并选择了我的问题首先 :) 我在大量谷歌搜索中找到了相同的答案,从一个工作的太阳系复制而来:earth.position.set(200* Math.cos(e_angleEARTH), 200* Math.sin(e_angleEARTH), 0); 这是我想出的解决方案,同样是 sin/cos。接下来要让我的 3D 太阳系更逼真,我想让你给出的例子中的轨道“椭圆”,它们也是圆形的。有什么提示吗?
  • 谢谢@Anarkie,这是我的荣幸。至于您跟进的问题,修改上面的示例,您可以通过添加修改器来拉长其中一个轴:var elongatedFactor = 1.5; theEarthAndMoon.position.x = Math.cos(radians) * earthOrbitRadius * elongatedFactor; theEarthAndMoon.position.z = Math.sin(radians) * earthOrbitRadius; 这将使 x 轴上的行进距离是 z 轴的 1.5 倍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
  • 2021-05-16
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多