Elliptic CurvesΒΆ
Animation control:
Visualization |
Frame Value |
|---|---|
Surface geometry |
functional parameter per frame |
Surface position |
constant |
Surface color |
color per frame |
Shading and highlighting |
fixed to the coordinate axis |
Axis coordinate |
constant |
Similar to the static plot from the Elliptic Curve example, the elliptic curve is defined, for coefficients a and b, as:
y2 = x3 + ax + b
Rearranging the above equation:
b = y2 - x3 - axSo, within a 3-D space (x,y,a):
b = f(x,y,a)Contour surfaces of constant b are shown above. Elliptic curves are the contour lines at the surface intersections with constant a planes.
In a similar manner, the initial equation can be arranged as:
a = ( y2 - b)/x - x2So, within a 3-D space (x,y,b):
a = f(x,y,b)In this case Contour surfaces of constant a are shown below. Here, elliptic curves are the contour lines at the surface intersections with constant b planes.
The following script is used for both plots using the boolean value of isAvar.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm,colors,colormaps
from matplotlib.animation import FuncAnimation
import s3dlib.surface as s3d
import s3dlib.pntcloud as ptc
import s3dlib.cmap_utilities as cmu
isAvar = True # controls if independent variable is a or b.
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
frame_to_time = lambda f : 2*f if f<0.5 else 2*(1-f) # forward to reverse sequence
def indicator_by_A(fig, A, vOld=None) :
symbol, blank = r'$\blacktriangleright$', r'$\blacksquare$'
horz, vBot, vRng = 0.82, 0.22, 0.56
vert = vBot + vRng*A
if vOld is not None: #.. cover current > symbol
fig.text(horz,vOld,blank, ha='right', va='center', fontsize='x-large', color='w')
fig.text(horz,vert,symbol, ha='right', va='center', fontsize='large')
return vert
# 1. Define function to examine .....................................
def elliptic3D(xyz,isAvar) :
x,y,z = xyz
if isAvar :
f = y**2 - (x**3 + z*x) # f = b(x,y,a)
else :
f = ( y**2 - z)/x - x**2 # f = a(x,y,b)
return f
drez, dmn, cmap = 9.99, [-3,3], cmu.section_cmap('jet',.15,.85,'subjet')
sdmn = np.array( [-2,2]) # surface value range (a or b)
Wabs = lambda t : sdmn[0] + (sdmn[1]-sdmn[0])*t
Fcolor = lambda v : cmap( (v-sdmn[0])/(sdmn[1]-sdmn[0]) )
ell3d = lambda xyz : elliptic3D(xyz,isAvar)
# 2. Setup and map surface .........................................
t=0
Fo = Wabs(t)
cloudObj = ptc.Point3DCloud(drez,domain=dmn)
cloudObj.map_vals_from_op(ell3d)
surface = cloudObj.valsurf(Fo,color=Fcolor(Fo))
if not isAvar : surface.clip(lambda c : np.abs(c[0])>0.01 ) # remove center yz-plane
lines = surface.contourLines(-2,-1.01,.005,1.01,2,color='k')
# 3. Construct figures, add surfaces, and plot ....................
ticks = [-3,-2,-1,0,1,2,3]
infoA = r'b = $y^2 - x^3 - ax$'
infoB = r'a = $\frac{y^2 -b}{x} - x^2$'
info = infoA if isAvar else infoB
zlabel = 'a' if isAvar else 'b'
cbarlabel = 'b' if isAvar else 'a'
fig = plt.figure(figsize=(5,4))
fig.text(0.75,0.95,info, ha='center', va='top', fontsize='x-large')
fig.text(0.1,0.85,'(x,y,'+zlabel+')', ha='left', va='top', fontsize='large')
ax = plt.axes(projection='3d', aspect='equal')
ax.view_init(21)
ax.set(xticks=ticks, yticks=ticks, zticks=ticks,
xlabel='x',ylabel='y',zlabel=zlabel)
norm = colors.Normalize(sdmn[0],sdmn[1])
scmp = cm.ScalarMappable(norm=norm,cmap=cmap)
cbar = plt.colorbar(scmp, ax=ax, shrink=0.6, pad=.12, ticks=ticks )
cbar.set_label(cbarlabel, rotation=0, labelpad = 5, fontsize='x-large')
prevIndicator = indicator_by_A(fig, t)
ax.add_collection3d(surface.shade(ax=ax).set_surface_alpha(.4))
ax.add_collection3d(lines.fade(.1))
s3d.add_boxCorner(ax,dmn)
fig.tight_layout(pad=1)
plt.show()
# 4. Animation ======================================================
def update_fig(frame):
global surface,prevIndicator,lines
surface.remove()
lines.remove()
Fo = Wabs(frame_to_time(frame))
surface = cloudObj.valsurf(Fo,color=Fcolor(Fo))
if not isAvar : surface.clip(lambda c : np.abs(c[0])>0.01 ) # remove center yz-plane
lines = surface.contourLines(-2,-1.01,.005,1.01,2,color='k')
prevIndicator = indicator_by_A(fig, frame_to_time(frame), prevIndicator)
ax.add_collection3d(surface.shade(ax=ax).set_surface_alpha(.4))
ax.add_collection3d(lines.fade(.1))
return
anim = FuncAnimation(fig, update_fig, frames, interval=interval, repeat=True)
anim.save('elliptic_curves_'+zlabel+'.html',writer='html')
msg = "saved {} frames, values: [{:.3f} to {:.3f}] @ {} milliseconds/frane"
print(msg.format(numFrames,np.min(frames),np.max(frames),interval))
print('DONE')
