用Python实现模拟太阳系运动方法
不懂用Python实现模拟太阳系运动方法?其实想解决这个问题也不难,下面让小编带着大家一起学习怎么去解决,希望大家阅读完这篇文章后大所收获。
资源素材
太阳系现在只有8大行星,连太阳一起,一共是9张图片。
defopenSolor(solar):defloadImg(name):str1=os.path.join(basePath,name+'.png')img=Image.open(str1)solar[name]=imgbasePath=r'D:\太阳系\素材'#loadImg('sun')loadImg('venus')loadImg('jupiter')loadImg('earth')loadImg('mars')loadImg('mercury')loadImg('neptune')loadImg('pluto')loadImg('uranus')loadImg('saturn')
基本运动原理
每颗行星的运动轨迹都是椭圆的,我们这里用一个参数方程来计算坐标:
x=cos(arc)*a
y=sin(arc)*b
其中,a,b 是椭圆的长轴和短轴,arc是运行角度,x,y是水平面坐标。
先上一张静态效果图吧!
参数的设置
为了效果好看,实际参数不可能是真实的。但有几个关键条件至少应该满足。首先行星顺序别弄错,行星轨道之间的间距不是等距的,而是渐增的。
其次是火星和木星直接有一个小行星带,所以这两个行星的轨道之间最好留出一个空隙。还有就是越往外圈的行星,绕行速度越慢。
definitSolar(posList):defgetNumber():returnrandom.randint(0,35)*10posList['sun']={'pos':(0,360),'rate':2,'scale':1,'radx':1,'layer':360}posList['mercury']={'rate':0.15,'radx':500,'arc':getNumber(),'rady':200,'speed':15}posList['venus']={'rate':0.2,'radx':550,'arc':getNumber(),'rady':250,'speed':10}posList['earth']={'rate':0.2,'radx':630,'arc':getNumber(),'rady':320,'speed':8}posList['mars']={'rate':0.2,'radx':740,'arc':getNumber(),'rady':410,'speed':6}posList['jupiter']={'rate':0.7,'radx':1050,'arc':getNumber(),'rady':650,'speed':4}posList['saturn']={'rate':1,'radx':1250,'arc':getNumber(),'rady':800,'speed':3}posList['uranus']={'rate':0.3,'radx':1480,'arc':getNumber(),'rady':970,'speed':2}posList['neptune']={'rate':0.3,'radx':1740,'arc':getNumber(),'rady':1160,'speed':2}
投影
一般的效果是将行星围绕太阳的公转面至于一个水平面上,然后投影到垂直的屏幕上。投影算法不难。
x=math.sin(math.radians(a))*radx+x0y=math.cos(math.radians(a))*rady+y0showX=xshowY=midY-H/(D+y)*y
其中,x,y是公转平面坐标,showX,showY是投影到垂直平面的坐标。H是平面的高度,D是屏幕到太阳系的距离。
从数据来看,我们的太阳系模型是一个非常小的模型,或者电脑屏幕非常大。因为这两者实际差不多大,以至于从观察者的视角就可以出现很明显的近大远小效果。从这种效果就可以知道,数据与真实值差别极为巨大。
近大远小的效果,只与y相关。
data['scale']=(y0+D)/(y+D)
遮挡效果
为了有真实感,行星之间、行星与轨道之间,轨道与太阳之间等等的遮挡效果是最关键的。
我们的做法是先画后半区,再画太阳,再画前半区。后半区中,远日行星先画;前半区中,近日行星先画。以保证正确的遮挡效果。
drawOrb(img,solar,posList,0,90,True)pasteSolor(img,solar,posList)drawOrb(img,solar,posList,90,180,False)
比较复杂一点的是行星与自身轨道之间的遮挡关系。必须实现一线穿一球的效果才好看。而且穿球位置不是固定不变的。这里,我们根据行星所在角度的不同,将轨道拆分为两半来画。
一部分轨道是被行星遮挡的,另一部分轨道遮挡行星,但留一些空间,以实现比较自然的穿球效果。
drawArc(arc1,arc)rate=posList[name]['rate']*posList[name]['scale']pic=solarImg[name].resize(effect.tupleRound(effect.tupleMul(solarImg[name].size,rate)),Image.ANTIALIAS)pos=effect.tupleRound(effect.tupleAdd(posList[name]['pos'],effect.tupleMul(pic.size,-0.5)))r,g,b,alpha=pic.split()img.paste(pic,pos,mask=alpha)#穿球点,随arc不同而不同#90度位置,在中心穿球,#越接近0或180度,越接近球边缘#根据这种性质,采用cos来模拟darc=abs(round(math.cos(math.radians(arc))*solarImg[name].size[1]*rate/50))#darc=abs(round(math.cos(math.radians(arc))*5))#print(name,arc,darc)drawArc(arc+darc,arc2)
感谢你能够认真阅读完这篇文章,希望小编分享用Python实现模拟太阳系运动方法内容对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,遇到问题就找亿速云,详细的解决方法等着你来学习!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。