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
from matplotlib.animation import FuncAnimation
import s3dlib.surface as s3d
import matplotlib.colors as mc

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

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

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

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

# 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', aspect='equal')
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)
#plt.show()

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

def update_fig(frame):
    global surface
    surface.remove()
    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

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

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