Earth InteriorΒΆ
Animation control:
Visualization |
Frame Value |
---|---|
Surface geometry |
functional clipping per frame |
Planar geometry |
functional parameter per frame |
Surface position |
fixed to the coordinate axis |
Planar position |
functional parameter per frame |
Surface color |
constant |
Planar color |
color map slice per frame |
Shading and highlighting |
fixed to the coordinate axis |
Axis coordinate |
constant |
import copy
import numpy as np
from matplotlib import colormaps
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import s3dlib.surface as s3d
import s3dlib.cmap_utilities as cmu
# 0. Define animation control parameters ............................
totalTime, f_domain, numFrames = 10, (0.0,1.0), 100 # time in seconds
frames=np.linspace(*f_domain, numFrames, endpoint=False)
interval = int(1000.0*totalTime/numFrames) # milliseconds
# 1. Define function to examine ....................................
rez, inner_size, core_size = 6, 0.7, 0.325
refmap = "hot"
ex_color = (colormaps[refmap](1))
core_color = (colormaps[refmap](1-core_size))
inner_color = (colormaps[refmap](1-inner_size))
def getParams(f):
a_list = [ 1.0, -inner_size, 1.0]
s_list = [ 1.0, 0.0, -1.0]
return s3d.frame_to_value(f,a_list,s_list)
def ringDef(rtz,minRad,maxRad) :
r,t,z = rtz
m = (maxRad-minRad)/2.0
b = (maxRad+minRad)/2.0
R = m*z + b
Z = np.zeros(len(z))
return R,t,Z
def getPlane(a,cSize) :
# -1 < a < 1
absA = np.abs(a)
b = np.sqrt( 1 - a*a )
if absA < cSize :
cmap = cmu.section_cmap(refmap,0,1-cSize)
plane = s3d.CylindricalSurface.grid(30,50,cmap=cmap)
plane.map_cmap_from_op( lambda rtz : 1-rtz[2] )
c = np.sqrt( cSize*cSize - a*a )
plane.map_geom_from_op( lambda rtz :ringDef(rtz,c,b))
plane.transform( [ [0,0,-1], [0,1,0], [1,0,0] ] , 1, [a,0,0] )
else :
if (1-absA) < 0.05 :
plane = s3d.PolarSurface(5, color=colormaps[refmap](0))
else :
cmap = cmu.section_cmap(refmap,0,1-absA)
plane = s3d.PolarSurface(5, cmap=cmap)
plane.map_cmap_from_op( lambda rtz : 1-rtz[0] )
plane.transform( [ [0,0,-1], [0,1,0], [1,0,0] ] , b, [a,0,0] )
return plane
def getSurfaces(f,core,interior,exterior) :
aVal, sVal = getParams(f)
surface = core + exterior.clip( lambda xyz : xyz[0]<aVal , usexyz=True )
if sVal>0 :
surface = surface + getPlane(aVal,core_size)
else :
if np.abs(aVal) < inner_size :
temp = interior.clip( lambda xyz : xyz[0]<aVal , usexyz=True )
surface = surface + temp # + getPlane(aVal,inner_size)
surface = surface + getPlane(aVal,inner_size)
return surface
# 2. Setup and map surface .........................................
fID = .265
core = s3d.SphericalSurface(rez-1, basetype='octa', color=core_color).transform(scale=core_size)
core.shade(.8).hilite(.5,[1,-1,1])
base_exterior = s3d.SphericalSurface(rez)
base_exterior.map_color_from_image('data/blue_marble.png').shade(.5,[0,0,1])
exterior = copy.copy(base_exterior)
base_interior = s3d.SphericalSurface(rez, basetype='octa', color=inner_color).transform(scale=inner_size)
base_interior.shade(.5,[-1,0,-1]).hilite(.5,[1,-1,-1])
interior = copy.copy(base_interior)
surface = getSurfaces(fID,core,interior,exterior)
# 3. Construct figure, add surfaces, and plot ......................
minmax = (-0.75,0.75)
fig = plt.figure(figsize=plt.figaspect(1), facecolor='k' )
ax = fig.add_subplot(111, projection='3d', aspect='equal', facecolor='k' )
ax.set(xlim=minmax, ylim=minmax, zlim=minmax)
ax.set_axis_off()
ax.view_init(elev=20,azim=-50)
ax.add_collection3d(surface)
fig.tight_layout(pad=0.1)
#plt.show()
# 4. Animation ======================================================
def update_fig(frame):
global surface
surface.remove()
interior = copy.copy(base_interior)
exterior = copy.copy(base_exterior)
surface = getSurfaces(frame,core,interior,exterior)
ax.add_collection3d(surface)
return
anim = FuncAnimation(fig, update_fig, frames, interval=interval, repeat=True)
anim.save('inner_earth.html',writer='html')
msg = "saved {} frames, values: [{:.3f} to {:.3f}] @ {} milliseconds/frane"
print(msg.format(numFrames,np.min(frames),np.max(frames),interval))