用Python显示真实的星空
还是先上图
本文讲述了如何画出真实的星空。
预备知识
要想展现真实的星空,首先要有真实恒星的位置坐标和亮度标记。其基本格式如下: {'long':0.023278328898474372,'lat':-0.09961466705757636,'light':46,'const':66}, {'long':0.024870941840919196,'lat':0.2338062439126301,'light':55,'const':62}, {'long':0.028107061526797,'lat':1.1204335039257496,'light':56,'const':18}, {'long':0.03660100303760025,'lat':0.5077259659824991,'light':21,'const':1}, {'long':0.04004802831028905,'lat':1.0323574005393255,'light':23,'const':18}, {'long':0.03944444109507185,'lat':0.3178583859888262,'light':55,'const':62}, {'long':0.040797071265367454,'lat':-0.488478858963941,'light':54,'const':74}, {'long':0.0410661312228549,'lat':-0.798444499556106,'light':39,'const':64}, {'long':0.043800486202076855,'lat':0.1945266317121166,'light':55,'const':66}, {'long':0.045036755271142,'lat':0.804111967609767,'light':50,'const':1}, {'long':0.043785947609407745,'lat':-1.4350775693910554,'light':53,'const':58}, {'long':0.04915283505929031,'lat':-0.2699684886295715,'light':49,'const':21}, {'long':0.050498187206605094,'lat':-0.4851966800391031,'light':54,'const':74},
每颗星星包含4个信息:天球经度long、天球纬度lat、亮度light(越小越亮)、const属于星座。
想象一下,所有的星星都镶嵌在天球上,它们的位置是固定的,所以它们被称为恒星。
星星的坐标用经纬度表示,就像地球上的位置用经纬度表示一样。当地球旋转时,我们看到的是天球的旋转。
我们熟悉的北极星,就在离天球北极很近的地方。
在天球旋转的过程中,它的位置几乎一动不动。也就是说,北极星的位置几乎总是固定在天空中。北极星之所以能指出方向,就是这个原理。
此外,星空是球形的,想要在屏幕上显示它,并设置了几组基本参数:
观测地的经纬度
观测日期和时间
观察者的观察角度和屏幕大小
在这些参数中,关系是这样的:观测地的维度是第一位的。观测地确定后,可以看到的星空是确定的(天球倾角)。只有赤道上能看到所有的星星,其他维度有些星星看不到。
最极端的情况是,在两极地区,只能看到半个天球(即半数星星)。
事实上,观测地点的经度、观测日期和观测时间是相等的,因为地球的旋转和旋转对于遥远的星空来说没有区别。
当确定观测点和观测日期时间时,理论上可以认为一天中大约有一半的星星可以看到。但是屏幕上可以显示的星星取决于你在哪里观看,屏幕有多大。
如能理解以上基本知识,请继续往下看。
星空计算
经过这几个步骤的计算:
1、为了便于计算,首先将每颗星星的经纬度转换为xyz的三维坐标。在这个转换过程中,我们看到的是正立的天球,北极向上,南极向下。
2、将观测地的纬度引入每个计算
3、将观测地经度、观测日期和观测时间结合起来,形成一个经度数据,并引入每个计算
4、将观察者的方向引入到每个计算中
5、将观察者的仰角引入每个计算器
6、向屏幕投影
代码如下:
defcalcStar(stars,Long,Lat,winLong,winLat,eyeDistant): Long=radians(Long) Lat=radians(Lat) winLong=radians(winLong) winLat=radians(winLat) forstarinstars: #print(star) #经纬度转换为xyz的三维坐标 x0=cos(star['long'])*cos(star['lat']) y0=sin(star['long'])*cos(star['lat']) z0=sin(star['lat']) #合并观测地的经度和日期 x1=x0*cos(Long)-y0*sin(Long) y1=x0*sin(Long)+y0*cos(Long) z1=z0 #观测地纬度 x2=x1*sin(Lat)-z1*cos(Lat) y2=y1; z2=x1*cos(Lat)+z1*sin(Lat) #观测者转身 x3=x2*cos(winLong)+y2*sin(winLong) y3=-x2*sin(winLong)+y2*cos(winLong) z3=z2 #观测者俯仰 x4=x3*sin(winLat)-z3*cos(winLat) y4=y3 z4=x3*cos(winLat)+z3*sin(winLat) #屏幕投影 star['visible']=(z2>0andz4>0) star['x']=x4*eyeDistant/z4 star['y']=y4*eyeDistant/z4 star['z']=z4
星星的可见条件是:高于地平线(z2)>在观察者面前(z4)>0),可见的星星是否真的显示在屏幕上,取决于它是否在屏幕显示范围内。
显示代码如下:
img=Image.new('RGBA',(1280,720),(0,0,120,255)#深蓝天 draw=ImageDraw.Draw(img) color=(255,255,0,255)#黄星 forstarinstars: #屏幕中心 x=round(-star['y']+640) y=round(star['x']+360) #亮度值越小越亮,这里用大小来表示 r=round(6-star['light']/10) ifvisible(star): #print(x,y) draw.ellipse((x-r,y-r,x+r,y+r),fill=color) img.show()
如何将月经、观测日期和观测时间结合起来
这个问题比想象的要复杂得多。如果你想真正准确,它将涉及许多细节,如平太阳日、真太阳日、恒星日、年差、月经和当地时间的差异等。
然而,幸运的是,这些误差并不大。如果你的目标不是科学研究,只考虑现代而不是古代和未来,一些误差即使被忽视也不会产生太大的影响。
在这里,我用一个简单但足够准确的经验公式来计算。输入观测月经、观测日期和时间,返回所谓的绝对月经,以此月经作为我们计算星空位置所使用的月经值。
代码如下:
defgetAbsLong(aLong,ayy,amm,add,ahh,amin): #忽略了年的影响 #月日的影响,首先计算太阳赤经 #春分点3月21日为经度0,平均每年365.25天,旋转360度,简单计算插值法 a=julianDay(ayy,amm,add) b=julianDay(ayy,3,21) v=0-(a-b)/365.25*360 #由于使用本地时间,基本上可以忽略经度+时区的影响(相互抵消) #时间的影响,中午12点,面对太阳赤经,每天24小时旋转360度,用插值简单计算 c=ahh*60+amin d=12*60 v=v-(c-d)/(24*60)*360 returnv
星座连线是怎么来的?
星座连接用来帮助我们了解星座的形状。结构很简单,就是指出一条线的相关性哪两点?这里不展开,详见代码。
{'star1':61,'star2':4,'const':1}, {'star1':60,'star2':61,'const':1}, {'star1':83,'star2':60,'const':1}, {'star1':83,'star2':109,'const':1}, {'star1':61,'star2':58,'const':1}, {'star1':58,'star2':22,'const':1}, {'star1':22,'star2':3097,'const':1}, {'star1':3097,'star2':3097,'const':1}, {'star1':3097,'star2':3088,'const':1}, {'star1':3007,'star2':3090,'const':1}, {'star1':142,'star2':61,'const':1},
更多Python知识,请关注Python视频教程!!