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 |
When changing the axis coordinate, the cmap shading 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 s3dlib.surface as s3d
import s3dlib.cmap_utilities as cmu
#.. Relative to the Viewer Animation
# 0. Define animation control parameters ............................
totalTime, f_domain, numFrames = 9, (0.0,1.0), 90 # time in seconds
frames=np.linspace(*f_domain, numFrames, endpoint=False)
interval = int(1000.0*totalTime/numFrames) # milliseconds
# 2. Setup surfaces and text ........................................
cmu.rgb_cmap_gradient([0.25,0.15,0],[1,.9,.75],'cardboard')
surfdata = [ ['tetra', [0,-2,0] ], ['octa', [2,1,0] ],
['icosa', [-2,1,0] ], ['cube', [0,0,2] ], ['dodeca', [0,0,-2] ] ]
view_elev, illum_dir = 33, [.5,1,.7]
start_f = 0
surface_set,surf_labels = [],[]
for data in surfdata :
surface = s3d.SphericalSurface.platonic(basetype=data[0])
surface.transform(translate=data[1])
surface_set.append(surface)
surf_labels.append( [ data[1][0], data[1][1], data[1][2] +1.3, data[0] ] )
# 3. Construct figure, add surfaces, and plot ......................
minmax = (-2,2)
fig = plt.figure(figsize=plt.figaspect(1))
ax = fig.add_subplot(111, projection='3d', aspect='equal')
ax.set(xlim=minmax, ylim=minmax, zlim=minmax)
for text in surf_labels : ax.text(*text,ha='center', va='center')
ax.set_axis_off()
azim = 360*start_f
ax.view_init(elev=view_elev, azim=azim)
illum = s3d.rtv(illum_dir, view_elev, azim)
for orig_surface in surface_set :
surface = copy.copy(orig_surface)
azim = 360*start_f
illum = s3d.rtv(illum_dir, view_elev, azim)
surface.map_cmap_from_normals( cmap='cardboard', direction=illum )
ax.add_collection3d(surface)
fig.tight_layout(pad=0)
#plt.show()
# 4. Animation ======================================================
def update_fig(frame):
azim = 360*frame
ax.view_init( elev=view_elev, azim=azim )
illum = s3d.rtv(illum_dir, view_elev, azim)
for orig_surface in surface_set :
surface = copy.copy(orig_surface)
surface.map_cmap_from_normals( cmap='cardboard', direction=illum )
ax.add_collection3d(surface)
return
anim = FuncAnimation(fig, update_fig, frames, interval=interval, repeat=True)
anim.save('bases.html',writer='html')
msg = "saved {} frames, values: [{:.3f} to {:.3f}] @ {} milliseconds/frane"
print(msg.format(numFrames,np.min(frames),np.max(frames),interval))