Dual Surface Face ColorΒΆ
Animation control:
Visualization |
Frame Value |
---|---|
Surface geometry |
constant |
Surface position |
fixed to the coordinate axis |
Surface color |
axis per frame using map_cmap_from_normals |
Shading and highlighting |
illumination direction per frame |
Axis coordinate |
elev and azim per frame using view_init |
Surface construction is based on the Inner and Outer Surface Coloring example. Color mapping is based on the view in the map_cmap_from_normals method, as in the Inner/Outer Surface Colormap example. This provides front and back surface coloring (direction=ax). Now, both the elev and azim change the shading per frame, same as the Python Cube animation, with the addition of the view information provided by the ax=ax parameter changing surface color.
import copy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import s3dlib.surface as s3d
import s3dlib.cmap_utilities as cmu
#.. Elev and Azim changes setting illumination direction and surface coloring.
# 0. Define animation control parameters ............................
totalTime, f_domain, numFrames = 5, (0.0,1.0), 90 # time in seconds
frames=np.linspace(*f_domain, numFrames, endpoint=False)
interval = int(1000.0*totalTime/numFrames) # milliseconds
# 1. Define functions to examine ....................................
def fig_8_knot(t,isInner) :
T = 2*np.pi*t
x = (2 + np.cos(2*T))*np.cos(3*T)
y = (2 + np.cos(2*T))*np.sin(3*T)
z = 3*np.sin(4*T)
f = 0.8 if isInner else 1.2
return f*x,f*y,f*z
inn_eight = lambda t : fig_8_knot(t,True)
out_eight = lambda t : fig_8_knot(t,False)
# 2. Setup and map surface .........................................
rez=8
view_elev, view_azim, illum_dir = 0, 0, [1,1,1]
bcmap = cmu.binary_cmap('orange', 'yellowgreen', name='orng_yg' )
line_1 = s3d.ParametricLine(rez,inn_eight)
line_2 = s3d.ParametricLine(rez,out_eight)
knot = line_1.get_surface_to_line(line_2)
orig_knot = copy.copy(knot)
# 3. Construct figure, add surface plot ............................
minmax = (-3,3)
fig = plt.figure(figsize=plt.figaspect(1), facecolor='black')
ax = plt.axes(projection='3d', facecolor='black')
ax.set(xlim=minmax,ylim=minmax,zlim=minmax)
ax.set_axis_off()
knot.map_cmap_from_normals(direction=ax,cmap=bcmap)
knot.shade(0.1,direction=illum_dir,ax=ax).hilite(.5,direction=illum_dir,ax=ax)
ax.add_collection3d(knot)
fig.tight_layout(pad=0)
#plt.show()
# 4. Animation ======================================================
def update_fig(frame):
view_elev = 360*frame
view_azim = 360*frame
if view_elev >= 270 : view_elev = view_elev - 360
ax.view_init( elev=view_elev, azim=view_azim )
knot = copy.copy(orig_knot)
knot.map_cmap_from_normals(direction=ax,cmap=bcmap)
knot.shade(0.1,direction=illum_dir,ax=ax).hilite(.5,direction=illum_dir,ax=ax)
ax.add_collection3d(knot)
return
anim = FuncAnimation(fig, update_fig, frames, interval=interval, repeat=True)
anim.save('fig_8_knot.html',writer='html')
msg = "saved {} frames, values: [{:.3f} to {:.3f}] @ {} milliseconds/frane"
print(msg.format(numFrames,np.min(frames),np.max(frames),interval))