import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.colors import LightSource
fig = plt.figure(figsize=(10, 8), facecolor='black')
ax = fig.add_subplot(111, projection='3d', facecolor='black')
ax.grid(False)
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_zlim(-2, 2)
ax.set_title('Moon Orbiting Earth with Realistic Lighting', color='white', pad=20)
def create_sphere(radius, center=(0, 0, 0), resolution=50):
u = np.linspace(0, 2 * np.pi, resolution)
v = np.linspace(0, np.pi, resolution)
x = radius * np.outer(np.cos(u), np.sin(v)) + center[0]
y = radius * np.outer(np.sin(u), np.sin(v)) + center[1]
z = radius * np.outer(np.ones(np.size(u)), np.cos(v)) + center[2]
return x, y, z
earth_radius = 0.8
x_earth, y_earth, z_earth = create_sphere(earth_radius)
light = LightSource(azdeg=0, altdeg=45)
rgb_earth = light.shade_normals(z_earth, fraction=1.0, blend_mode='hsv')
earth = ax.plot_surface(x_earth, y_earth, z_earth,
rstride=2, cstride=2,
facecolors=rgb_earth,
shade=False)
moon_radius = 0.2
orbit_radius = 1.5
x_moon, y_moon, z_moon = create_sphere(moon_radius, (orbit_radius, 0, 0), 30)
rgb_moon = light.shade_normals(z_moon - 0, fraction=1.0)
moon = ax.plot_surface(x_moon, y_moon, z_moon,
rstride=2, cstride=2,
color='lightgray',
facecolors=rgb_moon,
shade=False)
theta = np.linspace(0, 2*np.pi, 100)
x_orbit = orbit_radius * np.cos(theta)
y_orbit = orbit_radius * np.sin(theta)
z_orbit = 0.3 * np.sin(theta) # 使轨道略有倾斜
ax.plot(x_orbit, y_orbit, z_orbit, 'w', alpha=0.3, linestyle='dashed')
np.random.seed(42)
star_count = 200
star_x = np.random.uniform(-5, 5, star_count)
star_y = np.random.uniform(-5, 5, star_count)
star_z = np.random.uniform(-5, 5, star_count)
star_size = np.random.uniform(0.01, 0.1, star_count)
star_alpha = np.random.uniform(0.1, 1, star_count)
ax.scatter(star_x, star_y, star_z,
color='white', s=star_size, alpha=star_alpha)
def update(frame):
global moon
moon.remove()
angle = frame * 0.05
x_pos = orbit_radius * np.cos(angle)
y_pos = orbit_radius * np.sin(angle)
z_pos = 0.3 * np.sin(angle) # 轨道倾斜
x_moon, y_moon, z_moon = create_sphere(moon_radius, (x_pos, y_pos, z_pos), 30)
current_light = LightSource(azdeg=frame % 360, altdeg=45)
rgb_moon = current_light.shade_normals(z_moon - z_pos, fraction=1.0)
moon = ax.plot_surface(x_moon, y_moon, z_moon,
rstride=2, cstride=2,
color='lightgray',
facecolors=rgb_moon,
shade=False)
ax.view_init(elev=20, azim=frame % 360)
return moon,
ani = FuncAnimation(fig, update, frames=range(0, 360, 2),
interval=50, blit=False)
plt.tight_layout()
plt.show()