import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from ideal_poly_volume_toolkit.geometry import ( delaunay_triangulation_indices, lift_to_sphere_with_inf ) # The golden ratio configuration from seed 42 phi = (1 + np.sqrt(5)) / 2 z_points = np.array([ 0 + 0j, # z[0] 1 + 0j, # z[1] 2.6180 + 0j, # z[2] ≈ φ² 0.5 - 1.5388j, # z[3] 2.8917 - 2.6037j, # z[4] 0.5 + 1.5388j, # z[5] -1.6180 + 0j # z[6] ≈ -φ ]) # Get Delaunay triangulation triangles = delaunay_triangulation_indices(z_points) # Figure 1: Complex plane view with Delaunay triangulation fig1, ax1 = plt.subplots(figsize=(10, 10)) # Plot points real_coords = z_points.real imag_coords = z_points.imag ax1.scatter(real_coords, imag_coords, s=100, c='red', zorder=5) # Label points for i, z in enumerate(z_points): offset = 0.1 ax1.annotate(f'z[{i}]', (z.real + offset, z.imag + offset)) # Draw Delaunay triangles for tri in triangles: triangle = plt.Polygon([(real_coords[tri[j]], imag_coords[tri[j]]) for j in range(3)], fill=False, edgecolor='blue', linewidth=1.5) ax1.add_patch(triangle) ax1.set_xlabel('Real') ax1.set_ylabel('Imaginary') ax1.set_title('Golden Ratio Configuration in Complex Plane\nwith Delaunay Triangulation') ax1.grid(True, alpha=0.3) ax1.axis('equal') # Add circle at radius φ and φ² circle1 = plt.Circle((0, 0), phi, fill=False, linestyle='--', color='green', alpha=0.5) circle2 = plt.Circle((0, 0), phi**2, fill=False, linestyle='--', color='green', alpha=0.5) ax1.add_patch(circle1) ax1.add_patch(circle2) ax1.text(0.1, phi + 0.1, f'r = φ ≈ {phi:.3f}', color='green') ax1.text(0.1, phi**2 + 0.1, f'r = φ² ≈ {phi**2:.3f}', color='green') plt.savefig('golden_config_plane.png', dpi=150, bbox_inches='tight') print("Saved: golden_config_plane.png") # Figure 2: Stereographic projection to unit sphere fig2 = plt.figure(figsize=(12, 12)) ax2 = fig2.add_subplot(111, projection='3d') # Add infinity point for sphere projection z_with_inf = np.append(z_points, [np.inf]) sphere_points = lift_to_sphere_with_inf(z_with_inf) # Plot sphere points ax2.scatter(sphere_points[:, 0], sphere_points[:, 1], sphere_points[:, 2], s=100, c='red', depthshade=False) # Label points for i in range(len(sphere_points)): if i < len(z_points): label = f'z[{i}]' else: label = '∞' ax2.text(sphere_points[i, 0], sphere_points[i, 1], sphere_points[i, 2], label, fontsize=10) # Draw edges based on convex hull of sphere points # We need to determine which edges to draw based on the Delaunay triangulation # Each triangle in the plane corresponds to a face on the sphere edges_drawn = set() for tri in triangles: # Draw the three edges of each triangle for i in range(3): j = (i + 1) % 3 edge = tuple(sorted([tri[i], tri[j]])) if edge not in edges_drawn: edges_drawn.add(edge) p1 = sphere_points[edge[0]] p2 = sphere_points[edge[1]] ax2.plot([p1[0], p2[0]], [p1[1], p2[1]], [p1[2], p2[2]], 'b-', linewidth=1.5) # Also draw edges to infinity (north pole) # In ideal polyhedra, infinity is connected to certain boundary vertices inf_idx = len(z_points) # Index of infinity point # Connect infinity to vertices that are on the boundary of the convex hull in the plane from scipy.spatial import ConvexHull hull = ConvexHull(np.column_stack([real_coords, imag_coords])) for vertex_idx in hull.vertices: p1 = sphere_points[vertex_idx] p2 = sphere_points[inf_idx] ax2.plot([p1[0], p2[0]], [p1[1], p2[1]], [p1[2], p2[2]], 'g-', linewidth=1.5, alpha=0.7) # Draw unit sphere (transparent) u = np.linspace(0, 2 * np.pi, 50) v = np.linspace(0, np.pi, 50) x_sphere = np.outer(np.cos(u), np.sin(v)) y_sphere = np.outer(np.sin(u), np.sin(v)) z_sphere = np.outer(np.ones(np.size(u)), np.cos(v)) ax2.plot_surface(x_sphere, y_sphere, z_sphere, alpha=0.1, color='cyan') ax2.set_xlabel('X') ax2.set_ylabel('Y') ax2.set_zlabel('Z') ax2.set_title('Golden Ratio Configuration\nProjected onto Unit Sphere') # Set equal aspect ratio ax2.set_box_aspect([1,1,1]) ax2.view_init(elev=20, azim=45) plt.savefig('golden_config_sphere.png', dpi=150, bbox_inches='tight') print("Saved: golden_config_sphere.png") # Print configuration details print("\nConfiguration details:") print(f"Number of vertices: {len(z_points)} (plus infinity)") print(f"Number of triangles: {len(triangles)}") print(f"Triangles: {triangles}") # Analyze symmetries print("\nDistance analysis:") distances = {} for i in range(len(z_points)): for j in range(i+1, len(z_points)): d = abs(z_points[i] - z_points[j]) key = f"|z[{i}] - z[{j}]|" distances[key] = d # Group by similar distances unique_distances = {} for key, d in distances.items(): found = False for ud in unique_distances: if abs(d - ud) < 0.001: unique_distances[ud].append(key) found = True break if not found: unique_distances[d] = [key] print("\nGrouped distances:") for d in sorted(unique_distances.keys()): print(f" {d:.4f}: {unique_distances[d]}") plt.show()