Thumbnail.

Amplituhedron v1

Description

Although I liked the Faux Amplituhedron, I was curious to see what Chatgpt would come up with if I’d tell it to replace the placeholder polygon with “a true evaluation of your amplituhedron canonical form.” It did not disappoint.

(Please note that this doesn’t mean the resulting image is scientifically meaningful. If anything, it’s a science-inspired code/art experiment.)

import numpy as np
from PIL import Image
from hilbertcurve.hilbertcurve import HilbertCurve

# 1) Grid size
W = H = 4096
N = W * H  # 16,777,216

# 2) Camera parameters (pan and zoom) to frame the amplituhedron
# center_u, center_v specify the focal point in the unit square
# zoom >1 zooms in, <1 zooms out
center_u, center_v = 0.5, 0.3
zoom = 1.5
half_range = 0.5 / zoom
u_min, u_max = center_u - half_range, center_u + half_range
v_min, v_max = center_v - half_range, center_v + half_range

# 3) Build cyclic polygon data for A(n,1,2) on the moment curve
def build_amplituhedron_data(n=8):
    """
    Build cyclic polygon data on the planar moment curve for A(n,1,2).
    Returns Z (n×3 array) and precomputed triangle volumes and cross-products.
    """
    t = np.linspace(0.1, 0.9, n)
    Z = np.vstack([np.ones(n), t, t**2]).T
    Z0 = Z.mean(axis=0)
    tri_volume, cross_12, cross_20, cross_01 = [], [], [], []
    for i in range(n - 1):
        A, B = Z[i], Z[i+1]
        tri_volume.append(np.linalg.det(np.stack([Z0, A, B], axis=1)))
        cross_12.append(np.cross(A, B))
        cross_20.append(np.cross(B, Z0))
        cross_01.append(np.cross(Z0, A))
    return Z, Z0, np.array(tri_volume, float), cross_12, cross_20, cross_01

Z, Z0, tri_volume, cross_12, cross_20, cross_01 = build_amplituhedron_data(n=8)

# 4) Define the true amplituhedron canonical-form evaluator
def amplituhedron_value(u, v, epsilon=1e-12):
    """
    Evaluate the canonical-form density F(u,v) of A(n,1,2) at Y=(u,v,1).
    Regularizes exact boundary poles by epsilon.
    """
    Uy = u.ravel(); Vy = v.ravel()
    pts = np.column_stack([Uy, Vy, np.ones_like(Uy)])
    F_flat = np.zeros_like(Uy, float)
    for i in range(len(tri_volume)):
        d1 = pts.dot(cross_12[i])
        d2 = pts.dot(cross_20[i])
        d3 = pts.dot(cross_01[i])
        F_flat += tri_volume[i] / (d1 * d2 * d3 + epsilon)
    return F_flat.reshape(u.shape)

# 5) Sample the field with camera framing and rank pixels
us = np.linspace(u_min, u_max, W)
vs = np.linspace(v_min, v_max, H)
U, V = np.meshgrid(us, vs)
F = amplituhedron_value(U, V).ravel()
pixel_order = np.argsort(-F, kind='mergesort')

# 6) Generate full 24-bit palette and sort by a 3D Hilbert curve for smooth color continuity
colors = np.empty((256**3, 3), dtype=np.uint8)
idxs = np.arange(256**3, dtype=np.uint32)
colors[:,0] = (idxs >> 16) & 0xFF
colors[:,1] = (idxs >> 8) & 0xFF
colors[:,2] = idxs & 0xFF
# Build 3D Hilbert indexer on 8-bit coordinates
hc3 = HilbertCurve(p=8, n=3)
# Coordinates for each color
coords_rgb = np.column_stack([colors[:,0], colors[:,1], colors[:,2]])
# Compute Hilbert distances (slow but one-time)
distances = np.array(hc3.distances_from_points(coords_rgb.tolist()), dtype=np.uint32)
color_order = np.argsort(distances, kind='mergesort')

# 7) Assemble image and save
img_flat = np.empty((N,3), np.uint8)
img_flat[pixel_order] = colors[color_order]
img = img_flat.reshape((H, W, 3))
Image.fromarray(img).save('amplituhedron_true_unique_palette_hilbert.png')
print("Saved: amplituhedron_true_unique_palette_hilbert.png")

Author

ACJ
53 entries

Stats

Date
Colors16,777,216
Pixels16,777,216
Dimensions4,096 × 4,096
Bytes49,219,530