<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>lesson1-by-shawn.xie</title>
<!--引入Three.js-->
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<script type="text/javascript">
//宽高
const width = window.innerWidth - 30;
const height = window.innerHeight - 30;
//场景
const scene = new THREE.Scene();
//相机
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 5000000);
//渲染器
const renderer = new THREE.WebGLRenderer({
// alpha: true, //让背景透明,默认是黑色,以显示我们自己的背景图
});
//控制器
let cameraControls;
const revolutionSpeedRatio = 100;
//行星参数
const stars = [
{ name: '太阳', radius: 69.550, textureImg: 'Sun.png', centerPosition: { x: 0, y: 0, z: 0 }, rotationSpeed: Math.PI / 100 / 25.5/*自转速度*/, },
{ name: '水星', radius: 2.440, textureImg: 'Mercury.png', centerPosition: { x: 0, y: 0, z: 57909 / 500 }, rotationSpeed: Math.PI / 100 / 58/*自转速度*/, revolutionRadiusX: 69816.9 / 500, revolutionRadiusY: 46001.2 / 500, revolutionDiviseLength: 87.9/365*revolutionSpeedRatio/*公转速度有关,越大,转速越慢*/, revolutionDiviseInd: 0 },
{ name: '金星', radius: 6.051, textureImg: 'Venus.png', centerPosition: { x: 0, y: 0, z: 108200 / 500 }, rotationSpeed: Math.PI / 100 / 243/*自转速度*/, revolutionRadiusX: 108942 / 500, revolutionRadiusY: 107476 / 500, revolutionDiviseLength: 224.701/365*revolutionSpeedRatio, revolutionDiviseInd: 0 },
{ name: '地球', radius: 6.371, textureImg: 'Earth.png', centerPosition: { x: 0, y: 0, z: 147000 / 500 }, rotationSpeed: Math.PI / 100 / 1/*自转速度*/, revolutionRadiusX: 149600 / 500, revolutionRadiusY: 149580 / 500, revolutionDiviseLength: revolutionSpeedRatio, revolutionDiviseInd: 0 },
{ name: '火星', radius: 3.396, textureImg: 'Mars.png', centerPosition: { x: 0, y: 0, z: 227940 / 500 }, rotationSpeed: Math.PI / 100 / 1.05/*自转速度*/, revolutionRadiusX: 249200 / 500, revolutionRadiusY: 206600 / 500, revolutionDiviseLength: 686.971/365*revolutionSpeedRatio, revolutionDiviseInd: 0 },
{ name: '木星', radius: 69.911, textureImg: 'Jupiter.png', centerPosition: { x: 0, y: 0, z: 778330 / 500 }, rotationSpeed: Math.PI / 100 / 0.375/*自转速度*/, revolutionRadiusX: 817000 / 500, revolutionRadiusY: 741000 / 500, revolutionDiviseLength: 11.862*revolutionSpeedRatio, revolutionDiviseInd: 0 },
{ name: '土星', radius: 60.268, textureImg: 'Saturn.png', centerPosition: { x: 0, y: 0, z: 1429400 / 500 }, rotationSpeed: Math.PI / 100 / 0.4/*自转速度*/, revolutionRadiusX: 1514500 / 500, revolutionRadiusY: 1355250 / 500, revolutionDiviseLength: 29.4571*revolutionSpeedRatio, revolutionDiviseInd: 0 },
{ name: '海王星', radius: 24.622, textureImg: 'Neptune.png', centerPosition: { x: 0, y: 0, z: 4496000 / 500 }, rotationSpeed: Math.PI / 100 / 0.667/*自转速度*/, revolutionRadiusX: 4553946 / 500, revolutionRadiusY: 4452940 / 500, revolutionDiviseLength: 164.8*revolutionSpeedRatio, revolutionDiviseInd: 0 },
{ name: '天王星', radius: 25.362, textureImg: 'Uranus.png', centerPosition: { x: 0, y: 0, z: 28709900 / 500 }, rotationSpeed: Math.P / 100 / 0.65/*自转速度*/, revolutionRadiusX: 30044197.04 / 500, revolutionRadiusY: 2748938.461 / 500, revolutionDiviseLength: 84.0205*revolutionSpeedRatio, revolutionDiviseInd: 0 }
]
function addStar(star, index) {
const geometry = new THREE.SphereGeometry(star.radius, 100, 100);
const material = new THREE.MeshBasicMaterial({ /*wireframe: true,*/ map: new THREE.TextureLoader().load(star.textureImg) });
const starObj = new THREE.Mesh(geometry, material);
starObj.position.x = star.centerPosition.x;
starObj.position.y = star.centerPosition.y;
starObj.position.z = star.centerPosition.z;
scene.add(starObj)
//设置公转椭圆曲线
const curve = new THREE.EllipseCurve(
0, 0, // ax, aY
star.revolutionRadiusX, star.revolutionRadiusY, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
const points = curve.getPoints(star.revolutionDiviseLength)
//设置对象
stars[index].starObj = starObj;
stars[index].revolutionPoints = points;
}
//渲染
function animate() {
requestAnimationFrame(animate);
cameraControls.update();//更新控制器
renderer.render(scene, camera);
stars.forEach((star, index) => {
//自转
stars[index].starObj.rotation.y += 0.1;
//公转
if(index==0) //太阳不参与公转
return;
if (star.revolutionDiviseInd >= star.revolutionDiviseLength) {
stars[index].revolutionDiviseInd = 0;
} else {
stars[index].starObj.position.x = stars[index].revolutionPoints[star.revolutionDiviseInd].x;
stars[index].starObj.position.z = stars[index].revolutionPoints[star.revolutionDiviseInd].y;
star.revolutionDiviseInd++;
}
})
}
function threeStart() {
//设置渲染器
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
//设置控制器
cameraControls = new THREE.OrbitControls(camera, renderer.domElement);
//设置相机位置
camera.position.set(100, 200, 10000);
//增加辅助坐标轴
var axeshelper = new THREE.AxesHelper(6000);//轴辅助,参数为轴大小
scene.add(axeshelper);
//ArrowHelper,用于模拟方向的3维箭头对象.z轴/红,y轴/绿,x轴/蓝
scene.add(new THREE.ArrowHelper(new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 0, 0), 6000, 0x0000ff, 100));
//控制器设置
cameraControls.target = new THREE.Vector3(0, 1, 0); //绕目标坐标运动
//GridHelper,坐标格辅助对象. 坐标格实际上是2维线数组.
const gridHelper = new THREE.GridHelper( 12000/*size*/, 100/*divisions*/ );
scene.add( gridHelper );
stars.forEach((star, index) => {
addStar(star, index)
})
//渲染
animate();
}
</script>
</head>
<body onload='threeStart();'>
</body>
</html>