1. 项目准备:理解原理与备好“弹药”
想用Python画一个会转的3D地球?听起来很酷,但别被“3D”和“动画”吓到。其实它的核心思想,就像小时候玩的手工贴纸——你有一个圆形的气球(我们的地球轮廓),和一张印满了世界地图的长条形贴纸(专业点叫经纬度贴图或等距圆柱投影贴图)。你的任务,就是想办法把这张长条贴纸,严丝合缝地、没有褶皱地贴到圆气球上去,然后让气球慢慢转起来,我们看到的,就是贴纸上不同部分的内容依次展现。
所以,整个项目的“弹药”很简单:一张合适的地图图片,和Python的几个核心库。地图图片我强烈建议你去搜“Earth texture map”或“equirectangular projection map”,这种图的特点是宽高比是2:1,因为经度360度,纬度180度。网上资源很多,选一张清晰、美观的。我试过好几张,有的海洋颜色太深,转动起来效果不好;有的陆地边界太模糊。后来我常用的是NASA发布的一些公开的蓝色大理石(Blue Marble)图片,效果非常棒。
至于Python库,我们主要靠三个“老朋友”:
- PIL/Pillow:Python图像处理的瑞士军刀,负责创建新图片、读写像素。
- NumPy:数值计算的核心,没有它,我们对几十万个像素点的循环计算会慢到让你怀疑人生。用上NumPy的数组运算,速度能有百倍提升。
- imageio 或 Pillow 本身:用来把生成的一系列静态帧图片合成GIF动图。imageio用起来更简单直接。
安装它们就是一行命令的事:
pip install pillow numpy imageio
环境准备好,图片下载好,放在项目文件夹里,我们就可以开始了。记住,这个项目的所有“魔法”都发生在像素级别,我们不是在用现成的3D游戏引擎,而是在亲手计算每一个点应该是什么颜色,这种从底层实现的感觉,做完之后你会对图形学有完全不同的理解。
2. 核心算法拆解:从平面圆到球面坐标的映射
这是整个项目最硬核也最有趣的部分,我们得把思路理清楚。我们的目标是在一个300x300像素的画布上,画一个半径为150像素的圆(这就是我们的“地球”)。但是,我们不能简单地画一个蓝色圆,我们要把那张2:1的世界地图“贴”上去。
2.1 第一步:找到“地球”上的所有点
首先,我们得确定哪些像素点属于这个球(圆)的内部。这很简单,就是中学的勾股定理:计算每个像素点到画布中心点的距离,如果距离小于半径150,那这个点就在圆内,是需要我们处理的“地球表面点”。
import math
from PIL import Image
img = Image.new('RGBA', (300, 300), 'black') # 创建黑色背景
w, h = img.size
px_list = []
py_list = []
for i in range(w):
for j in range(h):
# 计算到中心点的距离
distance = math.sqrt((i - w/2)**2 + (j - h/2)**2)
if distance < 150: # 在圆内
px_list.append(i) # 收集X坐标
py_list.append(j) # 收集Y坐标
这里我用了两个列表分别存X和Y,是为了后续方便转换成NumPy数组进行计算。你可能会想,直接用一个列表存元组(x, y)不行吗?行,但后面用NumPy做向量运算时,拆开成两个数组会更方便。
2.2 第二步:平面圆点如何对应到3D球面?
这是最关键的一步。我们画布上的圆,其实是那个3D地球球体正对我们时,在2D平面上的投影。我们需要为圆内的每一个(x, y)点,找到它在3D球面上对应的经度和纬度。
想象一下:我们有一个单位球(半径=1),球心在画布中心。画布平面就是我们的屏幕平面(Z=0)。对于圆内一点(x, y),我们把它归一化(缩放到-1到1之间),那么它在屏幕平面上的坐标就是(x', y')


1158

被折叠的 条评论
为什么被折叠?



