Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_Orange_Spiral_Sphere.py
- import tkinter as tk
- import math
- import random
- import array
- import struct
- WIDTH, HEIGHT = 600, 600
- LINEWIDTH = 3
- FOV = 700.0
- SCALE = 230.0
- LAT_STEPS = 96
- LON_STEPS = 14
- SPIRAL_TURNS = 18
- POINTS_PER_SPIRAL = 720
- ANGLE_STEPS = 1440
- _step = 2 * math.pi / ANGLE_STEPS
- x_cache = [(math.cos(i * _step), math.sin(i * _step)) for i in range(ANGLE_STEPS)]
- y_cache = x_cache
- z_cache = x_cache
- def orange_depth(d):
- t = max(0.0, min(1.0, d))
- r = int(80 + 175 * t)
- g = int(20 + 120 * t)
- b = int(0 + 40 * t)
- return f'#{r:02x}{g:02x}{b:02x}'
- color_cache = [orange_depth(i / 255) for i in range(256)]
- root = tk.Tk()
- root.title("Orange Spiral Sphere")
- root.geometry("+-5+0")
- root.resizable(False, False)
- canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="black", highlightthickness=0)
- canvas.pack()
- W2 = WIDTH * 0.5
- H2 = HEIGHT * 0.5
- FOV = 700.0
- SCALE = 220.0
- pts_raw = array.array('d')
- for i in range(POINTS_PER_SPIRAL):
- t = 2 * math.pi * i / POINTS_PER_SPIRAL
- lat = math.pi * (i / (POINTS_PER_SPIRAL - 1))
- lon = SPIRAL_TURNS * t
- x = math.sin(lat) * math.cos(lon)
- y = math.cos(lat)
- z = math.sin(lat) * math.sin(lon)
- pts_raw.extend((x, y, z))
- RAW_FMT = f'{POINTS_PER_SPIRAL * 3}d'
- _px = array.array('d', bytes(POINTS_PER_SPIRAL * 8))
- _py = array.array('d', bytes(POINTS_PER_SPIRAL * 8))
- _dep = array.array('B', bytes(POINTS_PER_SPIRAL))
- lines = [
- canvas.create_line(0, 0, 1, 1, fill=color_cache[128], width=LINEWIDTH, capstyle=tk.ROUND)
- for _ in range(POINTS_PER_SPIRAL - 1)
- ]
- ix = random.randrange(ANGLE_STEPS)
- iy = random.randrange(ANGLE_STEPS)
- iz = random.randrange(ANGLE_STEPS)
- _coords = canvas.coords
- _config = canvas.itemconfig
- _after = root.after
- _unpack = struct.unpack
- _randint = random.randint
- def rotate():
- return _randint(8, 20)
- def draw_frame():
- global ix, iy, iz
- ix = (ix + rotate()) % ANGLE_STEPS
- iy = (iy + rotate()) % ANGLE_STEPS
- iz = (iz + rotate()) % ANGLE_STEPS
- cx, sx = x_cache[ix]
- cy, sy = y_cache[iy]
- cz, sz = z_cache[iz]
- m00 = cy*cz; m01 = cz*sx*sy - cx*sz; m02 = cx*cz*sy + sx*sz
- m10 = cy*sz; m11 = cx*cz + sx*sy*sz; m12 = cx*sy*sz - cz*sx
- m20 = -sy; m21 = cy*sx; m22 = cx*cy
- pts = _unpack(RAW_FMT, pts_raw)
- j = 0
- for i in range(POINTS_PER_SPIRAL):
- x = pts[j]; y = pts[j + 1]; z = pts[j + 2]
- j += 3
- rx = m00*x + m01*y + m02*z
- ry = m10*x + m11*y + m12*z
- rz = m20*x + m21*y + m22*z
- f = FOV / (rz + FOV) * SCALE
- _px[i] = rx * f + W2
- _py[i] = -ry * f + H2
- d = int((rz + 1.6) * 78.0)
- _dep[i] = 255 if d > 255 else (0 if d < 0 else d)
- for i in range(POINTS_PER_SPIRAL - 1):
- _coords(lines[i], _px[i], _py[i], _px[i + 1], _py[i + 1])
- _config(lines[i], fill=color_cache[(_dep[i] + _dep[i + 1]) >> 1])
- _after(1, draw_frame)
- draw_frame()
- root.mainloop()
Advertisement