#!/usr/bin/env python3
import mpl_toolkits.mplot3d.axes3d as axes3d
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.patches import Circle
import matplotlib.patheffects as PathEffects
# Generate meshgrid for the Klein bottle
u, v = np.linspace(0, 2*pi, 40), np.linspace(0, 2*pi, 40)
ux, vx = np.meshgrid(u, v)
x, y, z = surf(ux, vx)
# Get the dimensions of the Klein bottle for fixed axes
x_min, x_max = x.min(), x.max()
y_min, y_max = y.min(), y.max()
z_min, z_max = z.min() + 3, z.max() + 3
# Create a more festive Christmas-themed colormap
christmas_colors = LinearSegmentedColormap.from_list(
"ChristmasColors",
["darkred", "darkred", "white", "darkgreen", "darkgreen"]
)
# Set up the figure with a dark background for more contrast
plt.style.use('dark_background')
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(111, projection='3d')
# Plot the surface with enhanced Christmas colors
plot = ax.plot_surface(x, y, z, rstride=1, cstride=1,
cmap=christmas_colors,
linewidth=0, antialiased=True,
shade=True)
# Add Santa hat with rotation
hat_scale = 2.5
hat_x_offset = -12
hat_y_offset = 18
hat_z_offset = 1
# Rotation angles in radians
theta_x = np.pi/4 # Rotation around x-axis
theta_y = np.pi/6 - .25 # Rotation around y-axis
theta_z = np.pi/3 # Rotation around z-axis
(hat_x, hat_y, hat_z), (trim_x, trim_y, trim_z), (pom_x, pom_y, pom_z) = create_santa_hat(
hat_x_offset, hat_y_offset, hat_z_offset, hat_scale,
theta_x, theta_y, theta_z
)
# Plot the hat components
ax.plot_surface(hat_x, hat_y, hat_z, color='red', shade=True)
ax.plot_surface(trim_x, trim_y, trim_z, color='white', shade=True)
ax.plot_surface(pom_x, pom_y, pom_z, color='white', shade=True)
# Set fixed axis limits based on Klein bottle dimensions
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
ax.set_zlim(z_min, z_max)
# Customize the appearance
ax.set_facecolor('black')
fig.patch.set_facecolor('black')
# Scatter twinkling lights (random white dots)
np.random.seed(42) # For reproducibility
num_lights = 500
light_x = np.random.uniform(x.min()*2, x.max()*2, num_lights)
light_y = np.random.uniform(y.min()*2, y.max()*2, num_lights)
light_z = np.random.uniform(z_min*2, z_max*2, num_lights)
ax.scatter(light_x, light_y, light_z, color="white", s=1, alpha=0.8, label="Twinkling Lights")
# Add a festive title with glow effect
title = ax.set_title("Merry Christmas!",
fontsize=50,
fontweight='bold',
color="red",
pad=20)
title.set_path_effects([PathEffects.withStroke(linewidth=3, foreground='gold')])
# Remove axis for cleaner look
ax.set_axis_off()
# Show the plot
plt.show()