# Wormgat plus omgeving

import matplotlib.pyplot as plt
import numpy as np

from mpl_toolkits import mplot3d
from mpl_toolkits.mplot3d import Axes3D

plt.figure (figsize = (12, 12))

ax = plt.axes (projection = "3d")

# d is de afstand tussen de beide monden
d = 2

# k is de relatieve breedte van de keel
k = 0.15

# m is de breedte van de mond
m = 2

# s is de lengte van de omweg
s = 5

# dy laat de routes grafisch naar voren/achteren komen
dy = 0.1

# dz laat de omweg grafisch zakken
dz = 0.1

# Links/rechts verhouding
lrv = 1

# Route z-waarde ten opzichte van z-waarde van de ruimte
zw = 2

# Let op: de laatste waarde wordt niet meegenomen bij arange
stap = 0.01
u = np.arange (0, 1 + stap, stap)
v = np.arange (- d / 2, d / 2 + stap, stap)

u, v = np.meshgrid (u, v)

# Wormhole
# De abs is nodig om aan de grenzen van de meshgrid geen negatieve wortelinhoud te krijgen
x1 = m * (1 - (1 - k) * np.sqrt (np.abs (1 - (2 * v / d)**2))) * np.cos (2 * np.pi * u) / 2
y1 = m * (1 - (1 - k) * np.sqrt (np.abs (1 - (2 * v / d)**2))) * np.sin (2 * np.pi * u) / 2
z1 = v

# Bovenlangs rechts
x3 = s * u + (1 - u) * np.sqrt (np.abs (1 - v**2))
y3 = v
z3 = 0 * u + 1

# Onderlangs rechts
x4 = x3
y4 = y3
z4 = - z3

# Bovenlangs links
x5 = - lrv * s * u - (1 - u) * np.sqrt (np.abs (1 - v**2))
y5 = v
z5 = 0 * u + 1

# Onderlangs links
x6 = x5
y6 = y5
z6 = - z5

t = np.linspace (0, 1, 100)

# Omweg maken, bovenlangs
x7 = - lrv * s + (1 + lrv) * s * t
y7 = 0 * t + dy
z7 = zw - dz

# Shortcut, bovenlangs
x10 = - lrv * (s + k) + (lrv * (s + k) - zw) * t + k
y10 = 0 * t - dy
z10 = zw - dz

# Shortcut, door het wormgat, deel 1
d1 = 0.39
x11a = zw * np.sin (np.pi * t * d1) - zw + k
y11a = y10
z11a = zw * np.cos (np.pi * t * d1) - dz

# Shortcut, door het wormgat, deel 2
d2 = 0.78
x11b = - (zw * np.sin (np.pi * (d2 + (1 - d2) * t)) - zw + k)
y11b = y10
z11b = zw * np.cos (np.pi * (d2 + (1 - d2) * t)) - dz

# Shortcut, onderlangs
x12 = x10
y12 = y10
z12 = - z10 - 2 * dz

# Verder onderlangs
x9 = lrv * s * t - k + m
y9 = y10
z9 = - z7 - 2 * dz

ax.plot_surface (x1, y1, z1, color = "cyan")
ax.plot_surface (x3, y3, z3, color = "cyan")
ax.plot_surface (x4, y4, z4, color = "cyan")
ax.plot_surface (x5, y5, z5, color = "cyan")
ax.plot_surface (x6, y6, z6, color = "cyan")

#ax.plot3D (x7, y7, z7, color = "red")

ax.plot3D (x9, y9, z9, color = "yellow", zorder = 10)
ax.plot3D (x10, y10, z10, color = "yellow", zorder = 10)
ax.plot3D (x11a, y11a, z11a, color = "yellow", zorder = 10)
ax.plot3D (x11b, y11b, z11b, color = "yellow", zorder = 10)
#ax.plot3D (x12, y12, z12, color = "yellow", zorder = 10)

ax.set (xlabel = "x", ylabel = "y", zlabel = "z")
ax.set_aspect ("equal")

plt.axis ("off")
plt.savefig ("pythonplot.png", transparent = True)
plt.show ()
