some new stuff.
idk its all pretty fun! some C++ too!
This commit is contained in:
113
simulations/donut.c/tktcl.py
Normal file
113
simulations/donut.c/tktcl.py
Normal file
@@ -0,0 +1,113 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user