Conic SectionsΒΆ
Animation control:
Visualization | Frame Value |
---|---|
Contour Line position | distance parameter per frame |
Contour Line normal | yz-component parameter per frame |
Contour Line color | color per frame |
Shading and highlighting | fixed to the coordinate axis |
Axis coordinate | constant |
Based on the static plot from the Surface Contours example.
For this animation, the two parameters controlling the planar contours are varied with the frame: the distance of the plane from the origin, and the angle of the plane normal direction (parallel to the x-axis).
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib.animation as animation
from matplotlib.colors import ListedColormap
import s3dlib.surface as s3d
import numpy as np
#.. Animated Conic Sections
# 1. Define function to examine .....................................
a, b, c, d = 0.8, 0.4, -.4, -.6
cd = (c+d)/2
p=.5
dist = [ a, b, 0, 0, c, cd, d, -a ]
nang = [ 1, p, p, 0, 0, -p, -1, -1 ]
colors = ['C1','C2','C9','C0','C0','C1','C3' ]
def cone(rtz) :
r,t,z = rtz
R = np.abs(z)+0.001
return R,t,z
def get_line(A,coneSurf) :
# 0 < A < 1
distance,ang = s3d.frame_to_value(A,dist,nang)
color = s3d.frame_to_value(A,colors ,step=True)[0]
phi = np.pi*ang/2
direction = [ np.cos(phi),0,np.sin(phi)]
contour = coneSurf.contourLines(distance,-distance,direction=direction,color=color)
return contour.fade(0.2,15)
def indicator_by_A(fig, A, vOld=None) :
symbol, blank = r'$\blacktriangleright$', r'$\blacksquare$'
symbol, blank = r'$\blacktriangleleft$', r'$\blacksquare$'
horz, vBot, vRng = 0.895, 0.22, 0.56
vert = vBot + vRng*A
if vOld is not None:
fig.text(horz+.001,vOld,blank, ha='right', va='center', fontsize='x-large', color='w')
fig.text(horz,vert,symbol, ha='right', va='center', fontsize='large')
return vert
# 2. Setup and map surfaces .........................................
start_A = 0
rez=4
cmap = ListedColormap(colors)
surface = s3d.CylindricalSurface(rez,color='grey',cmap=cmap,lw=0.0)
surface.map_geom_from_op(cone)
surface.shade(.25).set_surface_alpha(.1)
line = get_line(start_A,surface)
# 3. Construct figure, add surface, plot ............................
fig = plt.figure(figsize=plt.figaspect(1))
ax = plt.axes(projection='3d')
ax.view_init(15)
plt.colorbar(surface.cBar_ScalarMappable, ax=ax, shrink=0.6, pad=.2, ticks=[] )
tL, tB, tD = 0.80, 0.25, 0.08
fig.text(tL,tB, 'Ellipses', ha='right')
fig.text(tL,tB+1*tD,'Parabolas', ha='right')
fig.text(tL,tB+2*tD,'Lines', ha='right')
fig.text(tL,tB+3.5*tD,'Hyperbolas', ha='right')
fig.text(tL,tB+5*tD,'Ellipses', ha='right')
fig.text(tL,tB+6*tD,'Circles', ha='right')
minmax = (-0.8,0.8)
ax.set(xlim=minmax, ylim=minmax, zlim=(-0.8,0.8))
ax.set_axis_off()
ax.add_collection3d(surface)
ax.add_collection3d(line)
prevIndicator = indicator_by_A(fig, start_A)
fig.tight_layout()
# 4. Animation ......................................................
def init_fig():
return line,
def update_fig(frame):
global line
global prevIndicator
ax.collections.remove(line)
line = get_line(frame,surface)
prevIndicator = indicator_by_A(fig, frame, prevIndicator)
ax.add_collection3d(line)
return line,
ani = FuncAnimation(fig, update_fig, frames=np.linspace(0.0, 1.0, 100),
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()