太阳系行星运行轨道模拟动画-基于htmlConvas

Posted 空中旋转篮球

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了太阳系行星运行轨道模拟动画-基于htmlConvas相关的知识,希望对你有一定的参考价值。

1.整理模拟动画缘由

最近儿子对宇宙和太阳系特别感兴趣,每天都要我给他将《宇宙有多大》、《神秘的太阳系》等书籍,不讲晚上不睡觉,经常会问一些难以回答的问题,有时候还要看一些太阳系的视频。因此,觉得可以整理一个太阳系模拟动画给儿子看,这个动画我们可以调整星球的大小(改变星球图片素材的大小),可以改变星球轨道的大小、颜色、星球绕行的速度等。效果如图:

静图如下:

gif动态图如下:

2.太阳系介绍

复制一波百度百科介绍,方便大家了解太阳系:太阳系-百度百科

2.1 基本介绍

太阳系(英文:Solar system)是一个受太阳引力约束在一起的天体系统,包括太阳、行星及其卫星、矮行星、小行星、彗星和行星际物质。太阳系位于距银河系中心大约2.4~2.7万光年的位置(银河系的恒星数量约在1000亿到4000亿之间,太阳只是其中之一。太阳以220千米/秒的速度绕银心运动,大约2.5亿年绕行一周,地球气候及整体自然界也因此发生2.5亿年的周期性变化。太阳运行的方向基本上是朝向织女,靠近武仙座的方向。

截至2019年10月,太阳系包括太阳、8个行星、近500个卫星和至少120万个小行星,还有一些矮行星和彗星。若以海王星轨道作为太阳系边界,则太阳系直径为60个天文单位,即约90亿千米。若以日球层为界,则太阳距太阳系边界可达100个天文单位(最薄处)。若以奥尔特云为界,则太阳系直径可能有20万天文单位。

太阳系的形成大约始于46亿年前一个巨型星际分子云的引力坍缩。太阳系内大部分的质量都集中于太阳,余下的天体中,质量最大的是木星。八大行星逆时针围绕太阳公转。此外还有较小的天体位于木星与火星之间的小行星带。柯伊伯带和奥尔特云也存在大量的小天体。还有很多卫星绕转在行星或者小天体周围。小行星带外侧的每颗行星都有行星环。

2.2 太阳系构成

名词辨析(依据2006IAU之决议)

行星 [18] 

1.环绕太阳且质量够大;

2.有足够的质量使本身的形状成为球体;

3.有能力清空邻近轨道的小天体。

水星、金星、地球、火星、木星、土星、天王星和海王星。

矮行星 [19] 

1.围绕太阳运动;

2.形状近似为球形;

3.无法清除邻近轨道上的其他小天体和物质。

谷神星冥王星阋神星鸟神星妊神星

卫星

环绕行星、矮行星或其他太阳系小天体的天体。

月球土卫六木卫四木卫五

彗星

1.围绕太阳运动;

2.主要由冰构成;

3.亮度和形状会因为离太阳距离而变化。

哈雷彗星海尔·波普彗星舒梅克·利维九号彗星(已解体)。

小行星

1.围绕太阳运动;

2.形状不规则,质量较小。

谷神星智神星婚神星灶神星义神星

 

太阳系结构概要

距离

(AU)

行星和矮行星

0

G2黄主序星:太阳

掠日彗星的近日点

太阳系的中心

0-2

太阳风层太阳风

行星际物质、太阳风层电流页

类地行星水星金星地球火星

近地小行星:阿登群、阿波罗群阿莫尔群

恩克型

2-3.2

谷神星、灶神星、智神星

小行星带

主带彗星

3.2-30

类木行星木星土星天王星海王星

特洛伊群半人马群

木星族哈雷型喀戎型

30-50

冥王星妊神星鸟神星

柯伊伯带

短周期彗星来源

50-75

阋神星

黄道离散盘

长周期彗星来源

非周期彗星:抛物彗星,双曲彗星

75-110

终端震波日鞘、太阳风层顶

太阳磁场边界

110-230

弓形震波

日球层顶

230-10000

星际物质

奥尔特云

10000-100000

太阳重力边界

100000以外

最近恒星:半人马座α比邻星

第二近恒星:半人马座阿尔法双星

太阳系外

2.3 太阳系行星参数

太阳和行星大小也只能大概按照比例设计了,不然有些小的看不见了。

八大行星主要参数

行星

轨道半长轴

AU

公转周期

平均轨道速度

km·s-1

偏心率

对黄道面倾斜

赤道和轨道面交角

水星

0.38709

87.9674

47.89

0.2056

7.00°

0.0

金星

0.72332

224.6960

35.03

0.0068

3.39°

177.3°

地球

1.00000

365.2564

29.79

0.0017

——

23.45°

火星

1.52366

686.9649

24.13

0.0934

1.85°

25.19°

木星

5.20336

11.862615

13.06

0.0483

1.31°

3.12°

土星

9.53707

29.447498

9.64

0.05415

2.48°

26.73°

天王星

19.19126

84.016846

6.81

0.04716

0.76°

97.86°

海王星

30.06869

164.79132

5.43

0.00858

1.77°

29.58°

行星

赤道半径:地球

质量:地球

平均密度

g/cm3

赤道逃逸速度

km/s

自转周期

卫星数量

水星

0.3825

0.05527

5.43

4.25

58.6462

0

金星

0.9488

0.81500

5.24

10.36

243.0187

0

地球

1.0000

1.00000

5.51

11.18

23.9345小时

1

火星

0.53226

0.10745

3.94

5.02

24.6230小时

2

木星

11.209

317.816

1.33

59.54

9.9250小时

63+

土星

9.449

95.1609

0.70

35.49

10.6562小时

82+ [24] 

天王星

4.007

14.5373

1.30

21.29

17.2399小时

27+

海王星

3.883

17.1471

1.76

23.71

16.1100小时

13+

3.太阳系动画实现代码

代码参考:canvas 太阳系的动画

素材来源:用python做一个漂亮的太阳系运动模拟

<!DOCTYPE html>
<html>
	<body style="background:#000">
	
		<canvas id="canvas" width="1920" height="1480" style="border:1px solid">
			Your browser does not support the canvas element.
		</canvas>
		
		<script type="text/javascript">
		    var sun = new Image();//创建图像对象0 = 太阳
		    var moon = new Image();//创建图像对象10 = 月球
		    var earth = new Image();//创建图像对象1 = 地球
		    var mercury = new Image();//创建图像对象2 = 水星
		    var venus = new Image();//创建图像对象3 = 金星

		    var mars = new Image();//创建图像对象4 = 火星
            var jupiter = new Image();//创建图像对象5 = 木星
            var saturn = new Image();//创建图像对象6 = 土星
		    var uranus = new Image();//创建图像对象7 = 天王星
            var neptune = new Image();//创建图像对象8= 海王星
            var pluto = new Image();//创建图像对象9 = 冥王星

		
			function init(){
			  //sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
               sun.src = 'sun_back1.png';
			   moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
			   //earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
			   earth.src = 'earth.png';
               mercury.src = 'mercury.png';
               venus.src = 'venus.png';
               mars.src = 'mars.png';
               jupiter.src = 'jupiter.png';
               saturn.src = 'saturn.png';
               uranus.src = 'uranus.png';
               neptune.src = 'neptune.png';
               pluto.src = 'pluto.png';

			 window.requestAnimationFrame(draw);//动画命令
			}
			
			function draw() {
			
			  var ctx = document.getElementById('canvas').getContext('2d');
			
			  ctx.globalCompositeOperation = 'destination-over';//谁先画,谁在上方(覆盖关系: 新图形画在 前一个图形的后面)
			  ctx.clearRect(-10,0,1920,1480); //清空画布,要更新动画, 必须清空画布 clear canvas
			
			  ctx.fillStyle = 'rgba(0,0,0,0.3)';//指定填充颜色
			  ctx.strokeStyle = 'rgba(75,153,255,0.99)';//指定绘线颜色
			  ctx.save();//保存状态 栈1 = 最初状态,原点在(0,0),没有移动过		  

			  ctx.translate(850,615);//把画布原点 从(0,0) 移动到 (700,615)
			  var time = new Date();//获取当前的日期和时间

			 // 画水星
             ctx.save();//保存当前的状态 栈2
			ctx.rotate( ((2*Math.PI)/3)*time.getSeconds() + ((2*Math.PI)/3000)*time.getMilliseconds() );//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
			ctx.drawImage(mercury,60,60);//把水星图形,添加到画布上
            ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

			    // 画金星
             ctx.save();//保存当前的状态 栈2
			ctx.rotate( ((2*Math.PI)/8)*time.getSeconds() + ((2*Math.PI)/8000)*time.getMilliseconds() );//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
			ctx.drawImage(venus,85,85);//把金星图形,添加到画布上
            ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

			 // 画火星 
            //var time = new Date();//获取当前的日期和时间
            ctx.save();//保存当前的状态 栈2
			ctx.rotate(((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
			ctx.drawImage(mars,152,152);//把火星图形,添加到画布上

            ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)
            // 画木星
             //var time = new Date();//获取当前的日期和时间
            // ctx.save();//保存当前的状态 栈2
			 ctx.rotate(((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
			// ctx.translate(130, 0);
			 ctx.drawImage(jupiter, 190, 190);//把木星图形,添加到画布上
			//ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

           //小行星
			ctx.save();//保存当前的状态 栈2
			ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 61500) * time.getMilliseconds());//月球旋转角度,和当前时间变换关联在一起
			ctx.translate(0, 28.5);//第三次 移动原点,(150+145,150)下移 28.5 (150+105,150+28.5)
			ctx.drawImage(moon, 175, 175);//画月球

			    // 画土星
			   // var time = new Date();//获取当前的日期和时间
             //ctx.save();//保存当前的状态 栈2
             ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 61500) * time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
             ctx.drawImage(saturn, 250, 250);//把土星图形,添加到画布上
             ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

			    //画天王星
			    //var time = new Date();//获取当前的日期和时间
             ctx.save();//保存当前的状态 栈2
             ctx.rotate(((2 * Math.PI) / 120) * time.getSeconds() + ((2 * Math.PI) / 120000) * time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
             ctx.drawImage(uranus, 335, 335);//把天王星图形,添加到画布上
             ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

			    // 画海王星
			    //var time = new Date();//获取当前的日期和时间
             ctx.save();//保存当前的状态 栈2
             ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 61500) * time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
             ctx.drawImage(neptune, 375, 375);//把海王星图形,添加到画布上
             ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

			    // 画冥王星
			    var time = new Date();//获取当前的日期和时间
             ctx.save();//保存当前的状态 栈2
             ctx.rotate(((2 * Math.PI) / 600) * time.getSeconds() + ((2 * Math.PI) / 610000) * time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
             ctx.drawImage(pluto, 417, 417);//把冥王星图形,添加到画布上
             ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)

			  // 画地球 Earth
			  //var time = new Date();//获取当前的日期和时间
             // ctx.save();//保存当前的状态 栈2
			  ctx.rotate(((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6150)*time.getMilliseconds());//从具体的日期和时间中提取出秒和毫秒字段,把顺时针旋转角度和 当前时间的 秒和毫秒变化 关联在一起
			  ctx.translate(175,0);//第二次移动原点,(150,150)水平向右移动105,把地球放在 绘线上
			  ctx.fillRect(0,-12,50,24); // 画1个矩形,作为地球图形上的另一半遮盖住,当作阴影 Shadow
			  ctx.drawImage(earth,-12,-12);//把地球图形,添加到画布上
			
			  //画月球 Moon
			  ctx.save();//保存当前的状态 栈2
			  ctx.rotate(((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6150)*time.getMilliseconds());//月球旋转角度,和当前时间变换关联在一起
			  ctx.translate(0,28.5);//第三次 移动原点,(150+145,150)下移 28.5 (150+105,150+28.5)
			  ctx.drawImage(moon,-1.5,-1.5);//画月球
			  
			  //画地球旋转轨道
			  ctx.restore();//恢复状态,当前状态=栈2
			  ctx.restore();//恢复状态,当前状态=栈1=最初状态 (原点没有移动过)
		  		
			  ctx.beginPath();
			   //ctx.arc(850,615,105,0,Math.PI*2,false);//水星
			  ctx.arc(850,615,140,0,Math.PI*2,false);//金星
			  ctx.arc(850,615,180,0,Math.PI*2,false); // Earth orbit,关联关系,半径 = 地球相对第二原点(700,615) 向右移动的距离
			  ctx.arc(850,615,240,0,Math.PI*2,false); // mars orbit,关联关系,半径 = 火星相对第二原点(700,615) 向右移动的距离
              ctx.arc(850,615,320,0,Math.PI*2,false); // 木星 orbit,关联关系,半径 = 木星相对第二原点(700,615) 向右移动的距离
              ctx.arc(850,615,420,0,Math.PI*2,false); //土星
              ctx.arc(850,615,510,0,Math.PI*2,false); //天王星
               ctx.strokeStyle = 'rgba(122,45,45,0.99)';//指定绘线颜色
              ctx.arc(850,615,560,0,Math.PI*2,true); //海王星
             // ctx.arc(850,615,600,0,Math.PI*2,true); //冥王星
              ctx.strokeStyle = 'rgba(247,255,45,0.99)';//重新指定绘线颜色
			  ctx.stroke();//绘线  各星球放在一起绘线会出现一个直线将各轨道连接起来

			  ctx.beginPath();
			  ctx.arc(850,615,105,0,Math.PI*2,false);//水星
                          ctx.strokeStyle = 'rgba(247,255,255,0.99)';//指定绘线颜色
			  ctx.stroke();//绘线

			  ctx.beginPath();
			  ctx.arc(850,615,275,0,Math.PI*2,false);//小行星单独绘线,用的月球图片,可以自己换成小行星的
                          ctx.strokeStyle = 'rgba(45,255,255,0.2)';//指定绘线颜色
			  ctx.stroke();//绘线

			  ctx.beginPath();
			  ctx.arc(850,615,600,0,Math.PI*2,true);//冥王星单独绘线
                          ctx.strokeStyle = 'rgba(200,255,255,0.8)';//指定绘线颜色
			  ctx.stroke();//绘线

                                                 
			//画太阳  
			 ctx.drawImage(sun,-10,0,1920,1480);
			 window.requestAnimationFrame(draw);//更新动画命令
			}                             
		  init();//重新获取图片资源和进行更新动画命令,图片资源不放在这里面,直接更新动画 也可以,效果不变		
		</script>		
	</body>
</html>

代码是可以进一步进行优化的,有些注释我都没有认真修改,这里大家可以回去修改。

4.最后

最后就是共享代码和素材资源了,大家可以自己下载,我设置为0分了,如果自动调整了,需要的同学可以留个邮箱,我看到了可以发过去。

https://download.csdn.net/download/soderayer/18431750

https://ezgif.com/这个网站视频可以转gif图片

以上是关于太阳系行星运行轨道模拟动画-基于htmlConvas的主要内容,如果未能解决你的问题,请参考以下文章

没有元素旋转的轨道动画

three.js模拟实现太阳系行星体系

OGL 4+/ GLSL / C++ - 尾随行星轨道

九大行星绕日运行的周期? 九大行星绕日运行的周期,公转自转各是多久?

在OpenGL中为行星绘制轨道试验[关闭]

怎么打造核心团队?