下面我将为你详细讲解如何实现 Python 绘画 3D 太阳系,并提供两条示例说明。
1. 准备工作
首先,需要安装以下依赖库:
numpy
matplotlib
mpl_toolkits.mplot3d
time
可以通过以下命令进行安装:
!pip install numpy matplotlib mpl_toolkits.mplot3d
2. 代码实现
2.1 数据准备
首先,需要准备太阳系行星的数据,包括行星的半径、日距、公转周期等信息。这些数据可以通过游戏、科普图书等途径获得。
我们以地球为例,可以定义如下参数:
earth_radius = 6378.137 # 地球半径,单位:千米
earth_sun_distance = 149597870.7 # 地球到太阳的距离,单位:千米
earth_angular_velocity = 0.00007292115 # 地球公转速度,单位:弧度/秒
2.2 绘图实现
然后,可以通过 matplotlib
库进行绘图。具体实现步骤如下:
- 创建 3D 坐标系:
fig = plt.figure()
ax = fig.gca(projection='3d')
- 创建行星球体:
earth = ax.plot_surface(
x, y, z, rstride=1, cstride=1,
linewidth=0, antialiased=False, alpha=0.6,
facecolors=plt.cm.Oranges(0.8), shade=False)
其中,x
、y
、z
分别是行星球体上的点在三维坐标系中的坐标。
- 通过不断更新行星的位置、姿态等信息,实现行星的运动轨迹:
for i in range(10000):
ax.cla() # 清空当前图像
# 计算地球当前的位置、姿态等信息
x, y, z = calc_earth_position(i, earth_sun_distance, earth_angular_velocity)
# 更新地球的位置
earth._offsets3d = (x, y, z)
# 重新绘制地球
ax.add_collection3d(earth)
plt.pause(0.01) # 暂停 0.01 秒,以便观察效果
其中,calc_earth_position
函数用于计算地球在第 i
时刻的位置、姿态等信息。最后通过 earth._offsets3d
更新地球的位置,并重新绘制地球。
2.3 完整代码
接下来,提供完整代码实现:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import time
earth_radius = 6378.137 # 地球半径,单位:千米
earth_sun_distance = 149597870.7 # 地球到太阳的距离,单位:千米
earth_angular_velocity = 0.00007292115 # 地球公转速度,单位:弧度/秒
def calc_earth_position(t, r, w):
x = r * np.cos(w*t)
y = r * np.sin(w*t)
z = 0
return x, y, z
fig = plt.figure()
ax = fig.gca(projection='3d')
u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j]
x = earth_radius * np.cos(u) * np.sin(v)
y = earth_radius * np.sin(u) * np.sin(v)
z = earth_radius * np.cos(v)
earth = ax.plot_surface(
x, y, z, rstride=1, cstride=1,
linewidth=0, antialiased=False, alpha=0.6,
facecolors=plt.cm.Oranges(0.8), shade=False)
for i in range(10000):
ax.cla() # 清空当前图像
# 计算地球当前的位置、姿态等信息
x, y, z = calc_earth_position(i, earth_sun_distance, earth_angular_velocity)
# 更新地球的位置
earth._offsets3d = (x, y, z)
# 重新绘制地球
ax.add_collection3d(earth)
plt.pause(0.01) # 暂停 0.01 秒,以便观察效果
3. 示例说明
3.1 绘制一个行星的运动轨迹
要绘制一个行星的运动轨迹,可以将上面的代码中的循环次数调整为 1
,即只计算一次行星的位置信息。
for i in range(1):
ax.cla() # 清空当前图像
# 计算地球当前的位置、姿态等信息
x, y, z = calc_earth_position(i, earth_sun_distance, earth_angular_velocity)
# 更新地球的位置
earth._offsets3d = (x, y, z)
# 重新绘制地球
ax.add_collection3d(earth)
plt.show() # 显示当前图像
3.2 绘制多个行星的运动轨迹
要同时绘制多个行星的运动轨迹,可以在循环中依次计算每个行星的位置信息,并分别更新每个行星的位置和姿态等信息。
具体实现代码如下:
# 行星信息列表,包括半径、距离、公转速度等
planet_list = [
{"name": "sun", "radius": 696340, "distance": 0, "angular_velocity": 0},
{"name": "mercury", "radius": 2439.7, "distance": 57909176, "angular_velocity": 0.00010471975},
{"name": "venus", "radius": 6051.8, "distance": 108208930, "angular_velocity": 0.0000872665},
{"name": "earth", "radius": 6378.137, "distance": 149597870.7, "angular_velocity": 0.00007292115},
{"name": "mars", "radius": 3396.19, "distance": 227936637, "angular_velocity": 0.00006027099},
{"name": "jupiter", "radius": 71492, "distance": 778547200, "angular_velocity": 0.000014544925},
{"name": "saturn", "radius": 60268, "distance": 1426666414, "angular_velocity": 0.00001203856},
{"name": "uranus", "radius": 25559, "distance": 2870658186, "angular_velocity": 0.000005236,
{"name": "neptune", "radius": 24764, "distance": 4503443661, "angular_velocity": 0.0000034711},
]
fig = plt.figure()
ax = fig.gca(projection='3d')
planet_objs = {} # 存储行星对象的字典
planet_paths = {} # 存储行星运动轨迹的字典
# 依次绘制每个行星
for planet in planet_list:
# 获取当前行星的半径、距离、公转速度等信息
name = planet["name"]
radius = planet["radius"]
distance = planet["distance"]
angular_velocity = planet["angular_velocity"]
# 创建行星球体,参考上面的代码
u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j]
x = radius * np.cos(u) * np.sin(v)
y = radius * np.sin(u) * np.sin(v)
z = radius * np.cos(v)
planet_objs[name] = ax.plot_surface(
x, y, z, rstride=1, cstride=1,
linewidth=0, antialiased=False, alpha=0.6,
facecolors=plt.cm.Oranges(0.8), shade=False)
# 计算当前行星的初始位置,参考上面的代码
x0, y0, z0 = calc_earth_position(0, distance, angular_velocity)
planet_objs[name]._offsets3d = (x0, y0, z0)
# 创建存储当前行星运动轨迹的对象
planet_paths[name], = ax.plot([x0], [y0], [z0],
color=plt.cm.Oranges(0.8),
lw=1, linestyle="-")
for i in range(10000):
ax.cla()
# 依次计算每个行星的位置,参考上面的代码
for planet in planet_list:
name = planet["name"]
radius = planet["radius"]
distance = planet["distance"]
angular_velocity = planet["angular_velocity"]
x, y, z = calc_earth_position(i, distance, angular_velocity)
planet_objs[name]._offsets3d = (x, y, z)
xdata, ydata, zdata = planet_paths[name]._verts3d
xdata = np.append(xdata, x)
ydata = np.append(ydata, y)
zdata = np.append(zdata, z)
planet_paths[name].set_data(xdata, ydata)
planet_paths[name].set_3d_properties(zdata)
ax.add_collection3d(planet_objs[name])
ax.plot(xdata, ydata, zdata, color=plt.cm.Oranges(0.8), lw=1, linestyle="-")
plt.pause(0.01)
通过上述代码,可以同时绘制多个行星的运动轨迹,并实现较为真实的 3D 效果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:你们要的Python绘画3D太阳系详细代码 - Python技术站