tpfto

Python script for Costa's minimal surface

Sep 28th, 2025 (edited)
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.48 KB | Source Code | 0 0
  1. # from https://mathstodon.xyz/@tpfto/115282798013947883
  2.  
  3. import mpmath as mpm
  4. import numpy as np
  5. import plotly.graph_objs as go
  6.  
  7. # prepare a polar mesh
  8. rh = np.linspace(0.05, 0.95, 70)
  9. th = np.linspace(-np.pi, np.pi, 90)
  10. rG, tG = np.meshgrid(rh, th)
  11. zz = rG * np.exp(1j * tG)
  12.  
  13. # Jacobi epsilon function, https://dlmf.nist.gov/22.16.E30
  14. def ellipjep(zz, m):
  15.     km = mpm.ellipk(m)
  16.     em = mpm.ellipe(m)
  17.     qm = mpm.qfrom(m=m)
  18.     fac = mpm.mp.pi / (2 * km)
  19.     uu = fac * zz
  20.     zn = fac * mpm.jtheta(4, uu, qm, 1) / mpm.jtheta(4, uu, qm)
  21.     res = zz * (em / km) + zn
  22.     return res
  23.  
  24. # vectorize the elliptic functions
  25. jaccn = np.vectorize((lambda u, m: complex(mpm.ellipfun("cn", u, m))))
  26. jacdn = np.vectorize((lambda u, m: complex(mpm.ellipfun("dn", u, m))))
  27. jacsn = np.vectorize((lambda u, m: complex(mpm.ellipfun("sn", u, m))))
  28. jacep = np.vectorize((lambda u, m: complex(ellipjep(u, m))))
  29.  
  30. # period
  31. cc = float(2 * mpm.ellipk(0.5))
  32.  
  33. # precompute elliptic functions over mesh
  34. st = jacsn(cc * zz, 0.5)
  35. ct = jaccn(cc * zz, 0.5)
  36. dt = jacdn(cc * zz, 0.5)
  37. et = jacep(cc * zz, 0.5)
  38.  
  39. # Costa minimal surface, https://doi.org/10.1007/BF02584707
  40. x = np.real(
  41.     (np.pi / 2 + (cc / 2) ** 2) * zz
  42.     - cc / 2 * (et + ct * dt / st)
  43.     - (np.pi * st * (1 / ct + ct)) / (4 * cc * dt)
  44. )
  45. y = np.imag(
  46.     (np.pi / 2 - (cc / 2) ** 2) * zz
  47.     + cc / 2 * (et + ct * dt / st)
  48.     - (np.pi * st * (1 / ct + ct)) / (4 * cc * dt)
  49. )
  50. z = np.sqrt(np.pi / 8) * np.log(np.abs(ct**2))
  51.  
  52. # 'birdie' from https://tpfto.wordpress.com/2019/04/17/faking-a-birds-colors-and-miscellanea/
  53. birdie = [
  54.     "#3E26A8", "#4536D4", "#484CEF", "#4562FC", "#347AFC", "#2C90F0", "#21A3E3", "#0CB3D3", "#12BEB9",
  55.     "#34C79C", "#5CCC76", "#94C94A", "#C8C129", "#F1BA37", "#FEC933", "#F5E327", "#F9FB14"
  56. ]
  57.  
  58. # and now, the plot...
  59. surface = go.Surface(x=x, y=y, z=z, colorscale=birdie, showscale=False)
  60. data = [surface]
  61.  
  62. psetxy = dict(
  63.     gridcolor="#EEE8D5",
  64.     zerolinecolor="#EEE8D5",
  65.     showbackground=True,
  66.     backgroundcolor="#839496",
  67.     range=[-4, 4]
  68. )
  69. psetz = dict(
  70.     gridcolor="#EEE8D5",
  71.     zerolinecolor="#EEE8D5",
  72.     showbackground=True,
  73.     backgroundcolor="#839496",
  74.     range=[-2.5, 2.5]
  75. )
  76. layout = go.Layout(
  77.     title="Costa's minimal surface",
  78.     scene=dict(
  79.         aspectmode="manual",
  80.         aspectratio=dict(x=1, y=1, z=0.625),
  81.         xaxis=psetxy,
  82.         yaxis=psetxy,
  83.         zaxis=psetz
  84.     ),
  85. )
  86.  
  87. fig = go.Figure(data=data, layout=layout)
  88. fig.show()
Tags: math geometry
Advertisement
Add Comment
Please, Sign In to add comment