Animated HypercubeΒΆ

../../_images/anim_hypercube.png

Animation control:

Visualization Frame Value
Surface geometry displacement parameter per frame
Surface position fixed to the coordinate axis
Surface color constant
Shading and highlighting fixed to the coordinate axis
Axis coordinate constant

Based on the static plot from the Hypercube example with animation script added to the end.

import numpy as np
import matplotlib.pyplot as plt
import s3dlib.surface as s3d
import matplotlib.colors as mc

#.. Hypercube
# 1. Define function to examine ....................................

# setup vertices ......
innerSize=0.5
backext = np.array( [ [-1,-1, 1], [-1, 1, 1], [-1, 1,-1], [-1,-1,-1] ] )
frntext = np.multiply(backext,[-1,1,1])
backinn = np.multiply(backext,innerSize)
frntinn = np.multiply(backinn,[-1,1,1])
temp = np.array([ backext, frntext, backinn, frntinn ])
v = np.reshape( temp,[-1,3])

# setup faces ......
extf = np.array([ [0,1,2,3], [1,2,6,5], [0,3,7,4], [4,7,6,5], [0,4,5,1], [3,2,6,7] ])
intf = np.add(extf,8)
edgf = [ [ 0, 8, 9, 1], [ 1, 9,13, 5], [ 5,13,12, 4], [ 4,12, 8, 0], 
         [ 3,11,10, 2], [ 2,10,14, 6], [ 6,14,15, 7], [ 7,15,11, 3], 
         [ 0, 3,11, 8], [ 1, 9,10, 2], [ 5, 6,14,13], [ 4,12,15, 7] ] 
f = np.concatenate((extf, intf, edgf), axis=0)

# 2. Setup and map surface .........................................
color = mc.to_rgba('C0',0.2)

surface = s3d.Surface3DCollection(v,f,color=color)
surface.shade(0.5,direction= [1,1,1], isAbs=True)

# 3. Construct figure, add surface plot ............................

fig = plt.figure(figsize=plt.figaspect(1))
ax = plt.axes(projection='3d')
minmax = (-1.2,1.2)
ax.set(xlim=minmax, ylim=minmax, zlim=minmax)
ax.set_title('4D-Hypercube\n'+str(surface))
ax.set_axis_off()
ax.view_init(20,-60)

ax.add_collection3d(surface)

fig.tight_layout(pad=0)

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

from matplotlib.animation import FuncAnimation
import matplotlib.animation as animation

ti = np.array( [1,3,0,2] ) 
v_translate = np.reshape( temp[ti]-temp, [-1,3] ).T
trans_vertex  = lambda xyz,delta : xyz + delta*v_translate
frame_2_delta = lambda f: 0.5*(1-np.cos(f*np.pi))

def init_fig():
    return surface

def update_fig(frame):
    global surface
    ax.collections.remove(surface)

    surface = s3d.Surface3DCollection(v,f,color=color)
    delta = frame_2_delta(frame)
    surface.map_geom_from_op(lambda xyz : trans_vertex(xyz,delta) )
    surface.shade(0.5,direction= [1,1,1], isAbs=True)

    ax.add_collection3d(surface)

    return surface

ani = FuncAnimation(fig, update_fig, frames=np.linspace(0.0, 1.0, 60),
                    init_func=init_fig, blit=False, repeat=True, interval=50)

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()