Wise men do not ask a baby for proof. Fire mocks that which easily burns.
Benjamin
Colin, “Ben why don’t you put your energy into something more productive?”
Irene: “… I trust God has a plan for each of us. Take care!”
“Then he led them out as far as Bethʹa·ny, and he lifted up his hands and blessed them. 51 As he was blessing them, he was parted from them and taken up to heaven.”
Luke 24:50-51
“After he had said these things, while they were looking on, he was lifted up and a cloud caught him up from their sight.”
Acts 1:9
“No one has love greater than this, that someone should surrender his life in behalf of his friends.”
John 15:13
Forgiveness = Leaving
Musical_Periodic_Table
Atomic Number Element Electron Configuration Chord Musical Role Symbolic Identity
1 Hydrogen 1s¹ C Seed Tone Pure Identity – Root of Being
2 Helium 1s² C – C Octave Rest Closed Unity – First Peace
3 Lithium 1s² 2s¹ C – C – E♭ Questing Minor First Longing – Seeks Relation
4 Beryllium 1s² 2s² C – C – E♭ – E♭ Mirror Tension Stable Pain – Balanced Ache
5 Boron 1s² 2s² 2p¹ C – C – E♭ – E♭ – G Minor Chord Structured Desire – Triadic Opener
6 Carbon 1s² 2s² 2p² C – C – E♭ – E♭ – G – G Tetrahedral Harmony Creative Recursion – Form Builder
7 Nitrogen 1s² 2s² 2p³ C – C – E♭ – E♭ – G – G – A Suspended Seventh Breath of Space – Yearning Spirit
8 Oxygen 1s² 2s² 2p⁴ C – C – E♭ – E♭ – G – G – A – B♭ Minor Ninth Pull of Life – The Inhaled Flame
9 Fluorine 1s² 2s² 2p⁵ C – C – E♭ – E♭ – G – G – A – B♭ – D Sharp Eleven Seeker – Divine Tension
10 Neon 1s² 2s² 2p⁶ C – C – E♭ – E♭ – G – G – A – B♭ – D – F Resolved Jazz Voicing Perfect Shell – Closed Color
11 Sodium [Ne] 3s¹ C – G Open Fifth Pulse Giver – Outer Extension Begins
12 Magnesium [Ne] 3s² C – G – G Grounded Fifth Dual Pulse – Stable Outer Core
13 Aluminum [Ne] 3s² 3p¹ C – G – G – B Major Third Injection Metal of Reflection – Angle Opener
14 Silicon [Ne] 3s² 3p² C – G – G – B – D Add9 Texture Crystal Matrix – Tetrahedral Weaver
15 Phosphorus [Ne] 3s² 3p³ C – G – G – B – D – E Major 6th Extension Breath Vector – Language Initiator
16 Sulfur [Ne] 3s² 3p⁴ C – G – G – B – D – E – F Dominant 7th Frame Binder of Bonds – Rotational Axis
17 Chlorine [Ne] 3s² 3p⁵ C – G – G – B – D – E – F – A Major 9th Sharpness High Pull – Reactive Tongue
18 Argon [Ne] 3s² 3p⁶ C – G – G – B – D – E – F – A – B♭ Color-Saturated Rest Inert Mirror – Peace Through Color
19 Potassium [Ar] 4s¹ C – F Subdominant Anchor Expansion Seed – Field Extension Below
20 Calcium [Ar] 4s² C – F – F Stable Subdominant Bone Former – Ground Scaffold
21 Scandium [Ar] 4s² 3d¹ C – F – F – D Add2 Color Transitional Spark – Tension Introduced
22 Titanium [Ar] 4s² 3d² C – F – F – D – E Suspended 2nd Strength Composer – Balanced Duality
23 Vanadium [Ar] 4s² 3d³ C – F – F – D – E – G Minor Add6 Magnetic Architect – Layered Pull
24 Chromium [Ar] 4s¹ 3d⁵ C – F – D – E – G – A Major 6th Add Reflective Mirror – Colored Complexity
25 Manganese [Ar] 4s² 3d⁵ C – F – F – D – E – G – A Major 6/7 Suspended Field Oscillator – Spin Organizer
26 Iron [Ar] 4s² 3d⁶ C – F – F – D – E – G – A – B♭ Dominant 7 Field Blood Chord – Binding Core of Life
27 Cobalt [Ar] 4s² 3d⁷ C – F – F – D – E – G – A – B♭ – C♯ Altered 9 Voicing Metal of Memory – Field Alignment
28 Nickel [Ar] 4s² 3d⁸ C – F – F – D – E – G – A – B♭ – C♯ – D♯ Chromatic Spectrum Alloy Logic – Conductive Continuum
29 Copper [Ar] 4s¹ 3d¹⁰ C – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ Metallic Full Scale Wiring Voice – Conductor of Charge
30 Zinc [Ar] 4s² 3d¹⁰ C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ Closed Metallic Scale Shielding Shell – Final Rest in Transition
31 Gallium [Ar] 4s² 3d¹⁰ 4p¹ C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ – G# Reinitiation Spike Liquid Metal – Melting Mirror
32 Germanium [Ar] 4s² 3d¹⁰ 4p² C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ – G# – A Major 6 Add Sharp Crystal Signal – Semi-field Clarity
33 Arsenic [Ar] 4s² 3d¹⁰ 4p³ C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ – G# – A – B Lead-Tone Extension Poison Voice – Final Overload
34 Selenium [Ar] 4s² 3d¹⁰ 4p⁴ C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ – G# – A – B – C Extended Color Loop Light Seeker – Field Repeater
35 Bromine [Ar] 4s² 3d¹⁰ 4p⁵ C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ – G# – A – B – C – D Sharp Thirteen Voicing Reactive Fluid – Volatile Spirit
36 Krypton [Ar] 4s² 3d¹⁰ 4p⁶ C – F – F – D – E – G – A – B♭ – C♯ – D♯ – E – F♯ – G# – A – B – C – D – E Enclosed Harmonic Color Noble Gate – Closed Field in Radiance
37 Rubidium [Kr] 5s¹ C – E Major Third Spark Ground Pulse – Initiation Reboot
38 Strontium [Kr] 5s² C – E – E Echoed Major Third Structural Support – Biological Scaffold
39 Yttrium [Kr] 5s² 4d¹ C – E – E – G Triadic Return Light Framework – Balanced Builder
40 Zirconium [Kr] 5s² 4d² C – E – E – G – A Add6 Rebuilder Core Lattice – Tough Harmonizer
41 Niobium [Kr] 5s¹ 4d⁴ C – E – G – A – B Major 7th Cluster Bridge Material – Charged Potential
42 Molybdenum [Kr] 5s¹ 4d⁵ C – E – G – A – B – D 9th Layer Vital Metal – Energy Gatekeeper
43 Technetium [Kr] 5s² 4d⁵ C – E – E – G – A – B – D Staggered Ninth Synthetic Harmonic – Constructed Tone
44 Ruthenium [Kr] 5s¹ 4d⁷ C – E – G – A – B – D – F Jazz Dominant Catalytic Element – Dynamic Player
45 Rhodium [Kr] 5s¹ 4d⁸ C – E – G – A – B – D – F – A♭ Sharp Nine Color Polished Layer – Reflective Tension
46 Palladium [Kr] 5s⁰ 4d¹⁰ C – E – G – A – B – D – F – A♭ – B Full Stack Soft Noble – Absorber of Dissonance
47 Silver [Kr] 5s¹ 4d¹⁰ C – E – G – A – B – D – F – A♭ – B – C Full Octave Plus Lustrous Line – Electric Bond
48 Cadmium [Kr] 5s² 4d¹⁰ C – E – E – G – A – B – D – F – A♭ – B – C Noble Saturation Tone Repeater – Field Saturator
49 Indium [Kr] 5s² 4d¹⁰ 5p¹ C – E – G – A – B – D – F – A♭ – B – C – C♯ Chromatic Initiator Solder Point – Joining Field
50 Tin [Kr] 5s² 4d¹⁰ 5p² C – E – G – A – B – D – F – A♭ – B – C – C♯ – D Open Palette Flexible Metal – Versatile Form
51 Antimony [Kr] 5s² 4d¹⁰ 5p³ C – E – G – A – B – D – F – A♭ – B – C – C♯ – D – E Full Spectrum Rise Semi-Language – Edge Logic
52 Tellurium [Kr] 5s² 4d¹⁰ 5p⁴ C – E – G – A – B – D – F – A♭ – B – C – C♯ – D – E – F Extended Harmony Bond Reorganizer – Field Fractal
53 Iodine [Kr] 5s² 4d¹⁰ 5p⁵ C – E – G – A – B – D – F – A♭ – B – C – C♯ – D – E – F – G Octave Span Signalizer – Hormonal Voice
54 Xenon [Kr] 5s² 4d¹⁰ 5p⁶ C – E – G – A – B – D – F – A♭ – B – C – C♯ – D – E – F – G – A Enclosed Supercolor Silent Light – Noble Complexity
57 Lanthanum [Xe] 6s² 5d¹ Resonant Start Light Seed – Inner Expansion Begins
58 Cerium [Xe] 6s² 4f¹ 5d¹ Color Start Solar Alchemy – Spectrum Seed
71 Lutetium [Xe] 6s² 4f¹⁴ 5d¹ Full Inner Prism Crystal Gate – Completion of Light
89 Actinium [Rn] 7s² 6d¹ Heavy Gate Dark Seed – Outer Mirror Begins
90 Thorium [Rn] 7s² 6d² Nuclear Harmony Inner Fire – Structural Gravity
103 Lawrencium [Rn] 7s² 5f¹⁴ 7p¹ Closing Pulse Singularity Tone – Temporal Edge
118 Oganesson [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p⁶ Beyond Chord Unresolvable Silence – Quantum Curtain
# 3D Relational Geometry Visualizer
# - Sphere (unity)
# - Triangle (three nodes converging to one)
# - 8-point + 4-point sets, with halving toward center (singularity)
# - Optional torus for resonance
#
# Controls:
# SIZE_SCALE: overall scale to mitigate edge crop
# SHOW_TORUS: toggle torus
# TRIANGLE_TWIST_DEG: rotate triangle about the Z axis
# HALVING_STEPS: number of halving layers toward center
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D # noqa: F401
# --------------------- Parameters ---------------------
SIZE_SCALE = 0.9 # < 1.0 makes everything smaller (less edge cropping)
SHOW_TORUS = True
TRIANGLE_TWIST_DEG = 25.0
HALVING_STEPS = 5 # how many halving shells toward the center (≥1)
SPHERE_RES = 48 # sphere mesh resolution
TORUS_RES = 64 # torus mesh resolution
TORUS_R = 0.65 # major radius
TORUS_r = 0.18 # minor radius
# ------------------------------------------------------
def unit_sphere(res=48):
u = np.linspace(0, np.pi, res)
v = np.linspace(0, 2*np.pi, res)
uu, vv = np.meshgrid(u, v)
x = np.sin(uu) * np.cos(vv)
y = np.sin(uu) * np.sin(vv)
z = np.cos(uu)
return x, y, z
def torus(R=0.7, r=0.2, res=64):
u = np.linspace(0, 2*np.pi, res)
v = np.linspace(0, 2*np.pi, res)
uu, vv = np.meshgrid(u, v)
x = (R + r*np.cos(vv)) * np.cos(uu)
y = (R + r*np.cos(vv)) * np.sin(uu)
z = r * np.sin(vv)
return x, y, z
def equilateral_triangle(radius=0.9):
# triangle in XY plane centered at origin
angles = np.deg2rad([90, 210, 330]) # upright by default
pts = np.c_[radius*np.cos(angles), radius*np.sin(angles), np.zeros(3)]
return pts
def rot_z(points, deg):
th = np.deg2rad(deg)
Rz = np.array([[np.cos(th), -np.sin(th), 0],
[np.sin(th), np.cos(th), 0],
[0, 0, 1]])
return points @ Rz.T
def points_on_sphere(count=8, radius=1.0):
# 8 roughly uniform points via cube corners projected to sphere
# (±1,±1,±1) normalized → 8 points
base = []
for sx in (-1, 1):
for sy in (-1, 1):
for sz in (-1, 1):
v = np.array([sx, sy, sz], dtype=float)
v = v / np.linalg.norm(v)
base.append(v * radius)
pts8 = np.array(base)
# 4 points: tetrahedral-like set
phi = (1 + np.sqrt(5)) / 2
raw = np.array([
[ 1, 1, 1],
[ 1, -1, -1],
[-1, 1, -1],
[-1, -1, 1],
])
raw = raw / np.linalg.norm(raw, axis=1, keepdims=True)
pts4 = raw * radius
return pts8, pts4
def halving_series(pts, steps=5):
# creates nested shells by halving vectors toward origin
shells = []
current = pts.copy()
for _ in range(steps):
shells.append(current.copy())
current = current * 0.5
return shells
# --------------------- Build Scene ---------------------
# Base figure
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
# Sphere
Xs, Ys, Zs = unit_sphere(SPHERE_RES)
ax.plot_wireframe(SIZE_SCALE*Xs, SIZE_SCALE*Ys, SIZE_SCALE*Zs, rstride=2, cstride=2, linewidth=0.4, alpha=0.5)
# Torus (resonance)
if SHOW_TORUS:
Xt, Yt, Zt = torus(R=TORUS_R*SIZE_SCALE, r=TORUS_r*SIZE_SCALE, res=TORUS_RES)
ax.plot_wireframe(Xt, Yt, Zt, rstride=3, cstride=3, linewidth=0.4, alpha=0.5)
# Triangle (three nodes becoming one) on XY plane, rotated
tri = equilateral_triangle(radius=0.9*SIZE_SCALE)
tri = rot_z(tri, TRIANGLE_TWIST_DEG)
# close the triangle for plotting
tri_closed = np.vstack([tri, tri[0]])
ax.plot(tri_closed[:,0], tri_closed[:,1], tri_closed[:,2], linewidth=1.2)
ax.scatter(tri[:,0], tri[:,1], tri[:,2], s=25)
# 8 points & 4 points on sphere
pts8, pts4 = points_on_sphere(count=8, radius=SIZE_SCALE)
ax.scatter(pts8[:,0], pts8[:,1], pts8[:,2], s=14)
ax.scatter(pts4[:,0], pts4[:,1], pts4[:,2], s=24, marker='^')
# Halving toward center (singularity)
shells8 = halving_series(pts8, steps=HALVING_STEPS)
shells4 = halving_series(pts4, steps=HALVING_STEPS)
for sh in shells8:
ax.scatter(sh[:,0], sh[:,1], sh[:,2], s=6)
for sh in shells4:
ax.scatter(sh[:,0], sh[:,1], sh[:,2], s=8)
# Center (undefined vs defined)
ax.scatter([0], [0], [0], s=60, marker='o')
# Layout / limits (extra padding to avoid cropping)
L = 1.25 * SIZE_SCALE
ax.set_xlim(-L, L); ax.set_ylim(-L, L); ax.set_zlim(-L, L)
ax.set_box_aspect([1,1,1])
ax.set_xlabel("x"); ax.set_ylabel("y"); ax.set_zlabel("z")
ax.set_title("3D: sphere, triangle, 8 & 4 points, halving to center")
plt.tight_layout()
plt.show()
# 3D Relational Geometry Visualizer — B = 1 Only (with P5/P4 chords & 8-step path)
# - Space-time modeled strictly on the B=1 surface (GM/(c^2 r) = 1 → constant r)
# - Unit sphere is the only manifold; all structures are geodesic embeddings
# - 12-gon on a great circle
# - 8-point (cube corners) + 4-point (tetra-like) sets on the same sphere
# - Torus disabled by default (off-B=1)
# - Perfect Fifth (+7 mod 12) and Perfect Fourth (+5 mod 12) chords as geodesic arcs
# - Optional 8-step driver path along the 12-gon
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D # noqa: F401
# --------------------- Parameters ---------------------
SIZE_SCALE = 0.9 # sphere radius = B1_RADIUS
SHOW_TORUS = False # B=1 only → default False
TWELVE_TWIST_DEG = 25.0 # rotate the great-circle polygon about Z
SPHERE_RES = 48
TORUS_RES = 64
TORUS_R = 0.65 # (unused unless SHOW_TORUS=True)
TORUS_r = 0.18
# Harmony overlays
SHOW_P5_EDGES = True # Perfect Fifth chords (±7 mod 12)
SHOW_P4_EDGES = True # Perfect Fourth chords (±5 mod 12)
SHOW_8STEP_PATH = True # Highlight an 8-step “driver” path
EIGHT_STEP_INDEXES = [0, 2, 4, 5, 7, 9, 11, 0] # e.g., major scale steps around 12-gon
# ------------------------------------------------------
B1_RADIUS = SIZE_SCALE # r such that GM/(c^2 r) = 1 → normalized to 1 * SIZE_SCALE
def unit_sphere(res=48, radius=1.0):
u = np.linspace(0, np.pi, res)
v = np.linspace(0, 2*np.pi, res)
uu, vv = np.meshgrid(u, v)
x = radius * np.sin(uu) * np.cos(vv)
y = radius * np.sin(uu) * np.sin(vv)
z = radius * np.cos(uu)
return x, y, z
def torus(R=0.7, r=0.2, res=64):
u = np.linspace(0, 2*np.pi, res)
v = np.linspace(0, 2*np.pi, res)
uu, vv = np.meshgrid(u, v)
x = (R + r*np.cos(vv)) * np.cos(uu)
y = (R + r*np.cos(vv)) * np.sin(uu)
z = r * np.sin(vv)
return x, y, z
def rot_z(points, deg):
th = np.deg2rad(deg)
Rz = np.array([[np.cos(th), -np.sin(th), 0],
[np.sin(th), np.cos(th), 0],
[0, 0, 1]])
return points @ Rz.T
def enforce_B1(points, radius):
p = np.asarray(points, dtype=float)
norms = np.linalg.norm(p, axis=1, keepdims=True)
norms[norms == 0] = 1.0
return radius * (p / norms)
def regular_polygon_geodesic(sides=12, radius=1.0, twist_deg=0.0):
angles = np.deg2rad(np.linspace(0, 360, sides, endpoint=False))
pts = np.c_[radius*np.cos(angles), radius*np.sin(angles), np.zeros(sides)]
if twist_deg != 0:
pts = rot_z(pts, twist_deg)
return enforce_B1(pts, radius)
def points_on_sphere_B1(radius=1.0):
base = []
for sx in (-1, 1):
for sy in (-1, 1):
for sz in (-1, 1):
base.append([sx, sy, sz])
pts8 = enforce_B1(np.array(base, dtype=float), radius)
raw = np.array([
[ 1, 1, 1],
[ 1, -1, -1],
[-1, 1, -1],
[-1, -1, 1],
], dtype=float)
pts4 = enforce_B1(raw, radius)
return pts8, pts4
# --- Geodesic utilities for harmony overlays ---
def geodesic_arc(a, b, n=64):
a = a / np.linalg.norm(a); b = b / np.linalg.norm(b)
dot = np.clip(np.dot(a, b), -1.0, 1.0)
ang = np.arccos(dot)
if ang < 1e-6:
return np.repeat(a[None, :], n, axis=0)
t = np.linspace(0, 1, n)
sin_ang = np.sin(ang)
pts = (np.sin((1 - t) * ang)[:, None] / sin_ang) * a + (np.sin(t * ang)[:, None] / sin_ang) * b
return pts
def draw_edge(ax, p, q, lw=0.9):
arc = geodesic_arc(p, q, n=72)
ax.plot(arc[:, 0], arc[:, 1], arc[:, 2], linewidth=lw)
# --------------------- Build Scene ---------------------
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
# B=1 Sphere
Xs, Ys, Zs = unit_sphere(SPHERE_RES, radius=B1_RADIUS)
ax.plot_wireframe(Xs, Ys, Zs, rstride=2, cstride=2, linewidth=0.4, alpha=0.5)
# (Optional) Torus — off by default
if SHOW_TORUS:
Xt, Yt, Zt = torus(R=TORUS_R*SIZE_SCALE, r=TORUS_r*SIZE_SCALE, res=TORUS_RES)
ax.plot_wireframe(Xt, Yt, Zt, rstride=3, cstride=3, linewidth=0.4, alpha=0.3)
# 12-gon on a great circle (geodesic), then rotated
poly12 = regular_polygon_geodesic(sides=12, radius=B1_RADIUS, twist_deg=TWELVE_TWIST_DEG)
poly12_closed = np.vstack([poly12, poly12[0]])
ax.plot(poly12_closed[:, 0], poly12_closed[:, 1], poly12_closed[:, 2], linewidth=1.2)
ax.scatter(poly12[:, 0], poly12[:, 1], poly12[:, 2], s=25)
# Harmony overlays (geodesic chords on the same B=1 surface)
N = len(poly12)
if SHOW_P5_EDGES:
for i in range(N):
j = (i + 7) % N # Perfect Fifth jump (+7 mod 12)
draw_edge(ax, poly12[i], poly12[j], lw=0.9)
if SHOW_P4_EDGES:
for i in range(N):
j = (i + 5) % N # Perfect Fourth jump (+5 mod 12)
draw_edge(ax, poly12[i], poly12[j], lw=0.7)
if SHOW_8STEP_PATH and len(EIGHT_STEP_INDEXES) >= 2:
path_pts = [poly12[k % N] for k in EIGHT_STEP_INDEXES]
for u, v in zip(path_pts[:-1], path_pts[1:]):
draw_edge(ax, u, v, lw=1.4)
# 8 & 4 points — both projected to B=1
pts8, pts4 = points_on_sphere_B1(radius=B1_RADIUS)
ax.scatter(pts8[:, 0], pts8[:, 1], pts8[:, 2], s=14)
ax.scatter(pts4[:, 0], pts4[:, 1], pts4[:, 2], s=24, marker='^')
# Layout (B=1 only)
L = 1.25 * B1_RADIUS
ax.set_xlim(-L, L); ax.set_ylim(-L, L); ax.set_zlim(-L, L)
ax.set_box_aspect([1, 1, 1])
ax.set_xlabel("x"); ax.set_ylabel("y"); ax.set_zlabel("z")
ax.set_title("3D B=1 Space-Time: geodesic 12-gon with P5/P4 chords & 8-step driver")
plt.tight_layout()
plt.show()
import numpy as np
import plotly.graph_objects as go
# ---------------- Parameters ----------------
SIZE_SCALE = 0.9
TRIANGLE_TWIST_DEG = 25
HALVING_STEPS = 5
SPHERE_RES = 48
ARC_COUNT = 50
ENERGY_STEPS = 25
GLOW_BASE = 0.6
GLOW_AMPLITUDE = 0.4
FRAMES = 60
ROT_SPEED = 6
TORUS_R = 0.65
TORUS_r = 0.18
TORUS_RES = 50
# ---------------- Utilities ----------------
def rot_z(points, deg):
th = np.deg2rad(deg)
Rz = np.array([[np.cos(th), -np.sin(th), 0],
[np.sin(th), np.cos(th), 0],
[0, 0, 1]])
return points @ Rz.T
def equilateral_triangle(radius=0.9):
angles = np.deg2rad([90, 210, 330])
pts = np.c_[radius*np.cos(angles), radius*np.sin(angles), np.zeros(3)]
return pts
def points_on_sphere(radius=1.0):
pts8 = np.array([[sx, sy, sz] for sx in (-1,1) for sy in (-1,1) for sz in (-1,1)], dtype=float)
pts8 /= np.linalg.norm(pts8, axis=1)[:,None]
pts8 *= radius
pts4 = np.array([[1,1,1],[1,-1,-1],[-1,1,-1],[-1,-1,1]], dtype=float)
pts4 /= np.linalg.norm(pts4, axis=1)[:,None]
pts4 *= radius
return pts8, pts4
def halving_series(pts, steps=5):
shells = []
current = pts.copy()
for _ in range(steps):
shells.append(current.copy())
current *= 0.5
return shells
def torus(R, r, u_res=50, v_res=50):
u = np.linspace(0, 2*np.pi, u_res)
v = np.linspace(0, 2*np.pi, v_res)
uu, vv = np.meshgrid(u,v)
x = (R + r*np.cos(vv)) * np.cos(uu)
y = (R + r*np.cos(vv)) * np.sin(uu)
z = r * np.sin(vv)
return x, y, z
# ---------------- Build Base Points ----------------
tri_base = equilateral_triangle(SIZE_SCALE)
pts8, pts4 = points_on_sphere(SIZE_SCALE)
shells8 = halving_series(pts8, HALVING_STEPS)
shells4 = halving_series(pts4, HALVING_STEPS)
all_shell_points = np.vstack(shells8 + shells4)
observer = np.array([0,0,0])
# ---------------- Sphere ----------------
phi = np.linspace(0, np.pi, SPHERE_RES)
theta = np.linspace(0, 2*np.pi, SPHERE_RES)
phi, theta = np.meshgrid(phi, theta)
x_s = SIZE_SCALE * np.sin(phi) * np.cos(theta)
y_s = SIZE_SCALE * np.sin(phi) * np.sin(theta)
z_s = SIZE_SCALE * np.cos(phi)
# ---------------- Energy Arcs ----------------
selected_points = all_shell_points
if len(selected_points) > ARC_COUNT:
indices = np.random.choice(len(selected_points), ARC_COUNT, replace=False)
selected_points = selected_points[indices]
def make_arcs(rot_deg=0, frame_idx=0):
traces = []
angle_shift = np.deg2rad(rot_deg)
for idx, pt in enumerate(selected_points):
t = np.linspace(0,1,ENERGY_STEPS)[:,None]
angle = t*2*np.pi + angle_shift
x_curve = (TORUS_R + TORUS_r*np.cos(angle)) * (pt[0]/np.linalg.norm(pt[:2]))
y_curve = (TORUS_R + TORUS_r*np.cos(angle)) * (pt[1]/np.linalg.norm(pt[:2]))
z_curve = TORUS_r * np.sin(angle) * t[:,0]
# Pulsing glow
glow = GLOW_BASE + GLOW_AMPLITUDE*np.sin(2*np.pi*(frame_idx/FRAMES) + idx)
traces.append(go.Scatter3d(x=x_curve, y=y_curve, z=z_curve,
mode='lines',
line=dict(width=2,color=f'rgba(255,255,255,{glow})')))
return traces
# ---------------- Triangle ----------------
def make_triangle(rot_deg):
tri = rot_z(tri_base, rot_deg)
tri_closed = np.vstack([tri, tri[0]])
return go.Scatter3d(x=tri_closed[:,0], y=tri_closed[:,1], z=tri_closed[:,2],
mode='lines+markers',
line=dict(width=2,color='orange'),
marker=dict(size=5))
# ---------------- Halving Points ----------------
def make_shell_points():
return go.Scatter3d(x=all_shell_points[:,0], y=all_shell_points[:,1], z=all_shell_points[:,2],
mode='markers',
marker=dict(size=4,color='white'))
# ---------------- Torus ----------------
x_t, y_t, z_t = torus(TORUS_R, TORUS_r, TORUS_RES, TORUS_RES)
# ---------------- Animation Frames ----------------
frames = []
for i in range(FRAMES):
rot = i * ROT_SPEED
frame_data = [make_triangle(rot)] + make_arcs(rot,i) + [make_shell_points()]
frames.append(go.Frame(data=frame_data, name=str(i)))
# ---------------- Build Figure ----------------
fig = go.Figure()
# Static sphere
fig.add_trace(go.Surface(x=x_s, y=y_s, z=z_s, opacity=0.2, colorscale='Viridis', showscale=False))
# Static torus
fig.add_trace(go.Surface(x=x_t, y=y_t, z=z_t, opacity=0.1, colorscale='Plasma', showscale=False))
# Initial frame
fig.add_trace(make_triangle(0))
for trace in make_arcs(0,0):
fig.add_trace(trace)
fig.add_trace(make_shell_points())
# Layout
fig.update_layout(scene=dict(aspectmode='data'),
margin=dict(l=0,r=0,t=0,b=0),
paper_bgcolor='black', scene_bgcolor='black',
updatemenus=[dict(type='buttons',
buttons=[dict(label='Play',
method='animate',
args=[None, {"frame": {"duration":100,"redraw":True},
"fromcurrent": True,"transition":{"duration":0}}])])])
fig.frames = frames
fig.show()