Moon with Rotating EarthΒΆ

../../_images/anim_earth_moon.png

Animation control:

Visualization

Frame Value

Surface geometry

constant

Surface position

rotation transform per frame

Surface color

constant

Shading and highlighting

fixed to the coordinate axis

Axis coordinate

constant

Based on the static plot from the Geometric and Color Image Mapping example.

Copies of the geometric and colored surface were used so that those two operations need not be repeated for each frame, only the rotation and shading.

import copy
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import s3dlib.surface as s3d

#.. Earth-Moon Animation

# 0. Define animation control parameters ............................

totalTime, f_domain, numFrames = 6, (0.0,360), 60   # time in seconds
frames=np.linspace(*f_domain, numFrames, endpoint=False)
interval = int(1000.0*totalTime/numFrames)          # milliseconds

# 2. Setup and map surfaces .........................................
start_theta = 0
rez=6
lightDirection = [1,0.8,1]

moon = s3d.SphericalSurface(rez-1)
moon.map_color_from_image('data/moon.png')
moon.shade(contrast=2,direction=lightDirection)
moon.transform(scale=[.4,.4,.4],translate=[-2,1,0.5])
# .......
earth = s3d.SphericalSurface(rez)
earth.map_color_from_image('data/earth.png')
earth.map_geom_from_image('data/elevation.png',0.06)
earthcopy = copy.copy(earth)
earthcopy.transform(scale=[1.2,1.2,1.2], translate=[.5,-.25,0],rotate=s3d.eulerRot(start_theta,0) )
earthcopy.shade(contrast=1.7,direction=lightDirection)
 
# 3. Construct figure, add surfaces, and plot ......................

fig = plt.figure(figsize=plt.figaspect(1), facecolor='k' )
ax = fig.add_subplot(111, projection='3d', facecolor='k', aspect='equal')
minmax = (-1,1)
ax.set(xlim=minmax, ylim=minmax, zlim=minmax)
ax.set_axis_off()

ax.add_collection3d(moon)
ax.add_collection3d(earthcopy)

#plt.show()

# 4. Animation ======================================================

def update_fig(frame):
    global earthcopy
    earthcopy.remove()
    earthcopy = copy.copy(earth)
    earthcopy.transform(scale=[1.2,1.2,1.2], translate=[.5,-.25,0],rotate=s3d.eulerRot(frame,0) )
    earthcopy.shade(contrast=1.7,direction=lightDirection)

    ax.add_collection3d(earthcopy)
    return

anim = FuncAnimation(fig, update_fig, frames, interval=interval, repeat=True)
anim.save('earth_moon.html',writer='html')

msg = "saved {} frames, values: [{:.3f} to {:.3f}] @ {} milliseconds/frane"
print(msg.format(numFrames,np.min(frames),np.max(frames),interval))