Platonic Solids¶
Animation control:
Visualization | Frame Value |
---|---|
Surface geometry | constant |
Surface position | fixed to the coordinate axis |
Surface color | constant |
Shading and highlighting | illumination direction per frame |
Axis coordinate | azim per frame using view_init |
Changing the axis coordinate and shading/highlighting results in ‘stationary viewer’ perception. The view is rotated about multiple surface objects.
import copy
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib.animation as animation
import s3dlib.surface as s3d
import s3dlib.cmap_utilities as cmu
#.. Relative to the Viewer Animation
# 1. Define functions to examine ....................................
view_elev, start_time = 33, 0 # 0.0 <= time <= 1.0
illum_dir = [.5,1,.7]
# 2. Setup and map surfaces .........................................
cmu.rgb_cmap_gradient([0.25,0.15,0],[1,.9,.75],'cardboard')
low_color, hi_color = [0.25,0.13,0], [1,.9,.75]
surfdata = [ ['tetra', [0,-2,0] ], ['octa', [2,1,0] ],
['icosa', [-2,1,0] ], ['cube', [0,0,2] ], ['dodeca', [0,0,-2] ] ]
# 3. Construct figure, add surfaces, and plot ......................
fig = plt.figure(figsize=plt.figaspect(1))
ax = fig.add_subplot(111, projection='3d')
minmax = (-1.8,1.8)
ax.set(xlim=minmax, ylim=minmax, zlim=minmax)
surface_set = []
for data in surfdata :
#surface = s3d.SphericalSurface(basetype=data[0],color=hi_color)
surface = s3d.SphericalSurface.platonic(basetype=data[0],color=hi_color)
surface.transform(translate=data[1])
surface_set.append(surface)
# text location dependent on object location
ax.text(data[1][0], data[1][1], data[1][2] +1.3, data[0],
horizontalalignment='center', verticalalignment='center')
# now, all object properties are dependent on azimuth and illumination direction.
azim = 360*start_time
illum = s3d.rtv(illum_dir, view_elev, azim)
surface_copies = []
for orig_surface in surface_set :
surface = copy.copy(orig_surface)
surface.map_cmap_from_normals( cmap='cardboard', direction=illum )
ax.add_collection3d(surface)
surface_copies.append(surface)
ax.set_axis_off()
ax.view_init(elev=view_elev, azim=azim)
plt.tight_layout()
# 4. Animation ......................................................
def init_fig():
return surface_copies,
def update_fig(frame):
global surface_copies
for surface in surface_copies :
ax.collections.remove(surface)
azim = 360*frame
illum = s3d.rtv(illum_dir, view_elev, azim)
surface_copies = []
for orig_surface in surface_set :
surface = copy.copy(orig_surface)
surface.map_cmap_from_normals( cmap='cardboard', direction=illum )
ax.add_collection3d(surface)
surface_copies.append(surface)
ax.view_init( elev=view_elev, azim=azim )
return surface_copies,
ani = FuncAnimation(fig, update_fig, frames=np.linspace(0.0, 1.0, 91),
init_func=init_fig, blit=False, repeat=True, interval=100)
print(">>>>>>>>>>>>>>> Animation completed, file save proceeds")
#ani.save('ZZZ.mp4') # use for movie file.
ani.save(None,writer=animation.FFMpegFileWriter()) # use for temp files.
print(">>>>>>>>>>>>>>> Save completed, screen display proceeds")
#plt.show()
print(">>>>>>>>>>>>>>> process completed")