Python中用代码实现旋转地球!
发布时间:2025-02-09 17:52:06

用python旋转地球
素材
这篇文章只讲旋转地球最简单、最常见的正面和侧面。
首先,你必须有一张360度的地图,效果如下图所示。在网上搜索,这样的图片很多,很容易得到。

它的特点是高度只有宽度的一半,因为地球每周有360度,而从南极到北极只有180度。这张360度的地图显示了地球在每个经纬度上的表面效果。仔细观察会发现,南北两极变形剧烈,中间地区类似于我们经常看到的地图。
我们称之为经纬度贴图。
基本原理
旋转地球之所以看起来像旋转,只是因为它上面显示的内容在变化。事实上,起点只是一个圆。我们所做的就是以合理的方式将经纬度地图中的像素粘贴到圆上。然后将帧图片连接到GIF动图。
贴图方法如下:
1、选择圆内的所有点。
2、计算每一点对应的经纬度。
3、从经纬度地图上获取经纬度对应的xy坐标
4、将像素写入图片中
5、制作GIF
计算过程是一个相对简单的球面几何,下面结合代码解释。
1 在圆内获得所有点
这个比较简单
img=Image.new('RGBA',(300,300)'black')
w=img.size[0]
h=img.size[1]
pxList=[]
pyList=[]
foriinrange(w):
forjinrange(h):
r=math.sqrt((i-w/2)**2+(j-h/2)**2)
ifr<150:
pxList.append(i)
pyList.append(j)2 计算经纬度
首先,从平面坐标中获得三维坐标
在球面上的任何一点上,都有一条规则是x2 + y2 + z2 = 1
利用这一原理,我们可以在圆内获得每个点的z值
根据x,y,计算球面的经纬度
为了使计算速度尽可能快,这里使用numpy
defcalcsperexy2XYZ(px,py,maxHeight,longOffset):
v0x=np.array(px)
v0y=np.array(py)
v03=np.subtract(v0x,maxHeight)
v04=np.subtract(v0y,maxHeight)
v1x=np.true_pide(v03,maxHeight)
v1y=np.true_pide(v04,maxHeight)
v07=np.power(v1x,2)
v08=np.power(v1y,2)
v09=np.add(v07,v08)
v0a=np.subtract(1,v09)
v1z=np.power(v0a,1/2)#z
#print('z:',max(v1z),min(v1z))
v1lat=np.multiply(v1y,math.pi/2)#lat
v0lon=np.arctan2(v1z,-v1x)
v1lon=np.add(v0lon,longOffset)#long
v2lon=np.fmod(v1lon,math.pi*2)#long
returnv2lon,v1lat3 获取经纬度对应的xy坐标
这是一个简单的坐标映射
defcalcshperlatlong2XY(vlon,vlat,width,height): v3x0=np.multiply(vlon,width/2/math.pi) v3y0=np.multiply(vlat,height/math.pi) v3y1=np.add(v3y0,height/2) v3x2=v3x0.astype(np.integer) v3y2=v3y1.astype(np.integer) returnv3x2,v3y2
4 获得像素点并写入图片
首先,将载入经纬度贴图的材料转换为numpy格式
imgBack=Image.open('EARTH_small.bmp')
width=imgBack.size[0]
height=imgBack.size[1]
imgBack=imgBack.convert('RGBA')
arrayBack=np.array(imgBack)注意转换后的XY是相反的,取点并直接赋值
color=arrayBack[npy,npx] foriinrange(len(pxList)): x=pxList[i] y=pyList[i] cc=color[i] #print(cc) cc=tuple(cc) img.putpixel((x,y),cc)
5 GIF制作
imageio库使用
frames=[]
foriinrange(0,360,10):
a=-i*math.pi/180
img=getPic(a)
str1='temp%03d.png'%i
img.save(str1)
im=imageio.imread(str1)
frames.append(im)
#img.show()
imageio.mimsave('earth.gif',frames,'GIF',duration=0.25)更多Python知识,请关注Python视频教程!!
