import tkinter as tk import math # Torus parameters theta_spacing = 0.07 phi_spacing = 0.02 R1 = 1 R2 = 2 K2 = 5 chars = ".,-~:;=!*#$@" # luminance chars # Base character grid (like "screen resolution") screen_width = 80 screen_height = 24 # Tkinter setup root = tk.Tk() root.title("Spinning Torus Demo") # Get window size and calculate scaling window_width = 800 window_height = 400 root.geometry(f"{window_width}x{window_height}") # Calculate character cell size to fit screen dimensions cell_width = window_width // screen_width cell_height = window_height // screen_height font_size = min(cell_width, cell_height) font = ("Courier", font_size) canvas = tk.Canvas(root, width=window_width, height=window_height, bg="black") canvas.pack() # Pre-create text items for the character grid text_items = [] for y in range(screen_height): row = [] for x in range(screen_width): item = canvas.create_text( x*cell_width, y*cell_height, text=' ', anchor='nw', fill='white', font=font ) row.append(item) text_items.append(row) # Calculate K1 based on screen width K1 = screen_width * K2 * 3 / (8 * (R1 + R2)) def render_frame(A, B): cosA = math.cos(A) sinA = math.sin(A) cosB = math.cos(B) sinB = math.sin(B) output = [[' ' for _ in range(screen_height)] for _ in range(screen_width)] zbuffer = [[0 for _ in range(screen_height)] for _ in range(screen_width)] theta = 0 while theta < 2 * math.pi: costheta = math.cos(theta) sintheta = math.sin(theta) phi = 0 while phi < 2 * math.pi: cosphi = math.cos(phi) sinphi = math.sin(phi) circlex = R2 + R1 * costheta circley = R1 * sintheta x = circlex * (cosB * cosphi + sinA * sinB * sinphi) - circley * cosA * sinB y = circlex * (sinB * cosphi - sinA * cosB * sinphi) + circley * cosA * cosB z = K2 + cosA * circlex * sinphi + circley * sinA ooz = 1 / z xp = int(screen_width / 2 + K1 * ooz * x) yp = int(screen_height / 2 - K1 * ooz * y) L = cosphi * costheta * sinB - cosA * costheta * sinphi - sinA * sintheta + cosB * (cosA * sintheta - costheta * sinA * sinphi) if L > 0: if 0 <= xp < screen_width and 0 <= yp < screen_height: if ooz > zbuffer[xp][yp]: zbuffer[xp][yp] = ooz luminance_index = int(L * 8) if luminance_index >= len(chars): luminance_index = len(chars) - 1 output[xp][yp] = chars[luminance_index] phi += phi_spacing theta += theta_spacing # Update Tkinter canvas for y in range(screen_height): for x in range(screen_width): canvas.itemconfigure(text_items[y][x], text=output[x][y]) # Animation loop A = 0 B = 0 def animate(): global A, B render_frame(A, B) A += 0.07 B += 0.03 root.after(30, animate) animate() root.mainloop()