Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_Lissajous_Curve.py
- import tkinter as tk
- import math
- WIDTH, HEIGHT = 500, 500
- W2, H2 = WIDTH//2, HEIGHT//2
- STEPS = 200
- A = B = C = 180
- a, b, c = 3, 4, 5
- dx, dy, dz = 0.0, math.pi / 2, math.pi / 3
- root = tk.Tk()
- root.title("Lissajous Curve")
- root.geometry("+-5+0")
- canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="black", highlightthickness=0)
- canvas.pack()
- color_cache = {}
- line_segments_cache = []
- def rgb_to_hex(r, g, b):
- return f"#{r:02x}{g:02x}{b:02x}"
- def precompute_line_segments():
- global line_segments_cache
- line_segments_cache = [(i, i + 1) for i in range(STEPS)]
- precompute_line_segments()
- def depth(depth_t):
- return round(depth_t * 100) / 100
- def get_color_for_depth(depth_t, min_depth, max_depth):
- quantized_depth = depth(depth_t)
- cache_key = (quantized_depth, min_depth, max_depth)
- if cache_key in color_cache:
- return color_cache[cache_key]
- if max_depth > min_depth:
- norm_depth = 1.0 - (depth_t - min_depth) / (max_depth - min_depth)
- norm_depth = max(0, min(1, norm_depth))
- else:
- norm_depth = 0.5
- r = int(0 + norm_depth * 136)
- g = int(51 + norm_depth * 204)
- b = int(102 + norm_depth * 153)
- width = max(2, int(5 * norm_depth))
- color_cache[cache_key] = (rgb_to_hex(r, g, b), width)
- pts = []
- for i in range(STEPS + 1):
- t = 2 * math.pi * i / STEPS
- x = A * math.sin(a * t + dx)
- y = B * math.sin(b * t + dy)
- z = C * math.sin(c * t + dz)
- pts.append((x, y, z))
- angle = 0.0
- w = 21
- w2 = w // 2
- def draw():
- global angle
- canvas.delete("all")
- ca, sa = math.cos(angle), math.sin(angle)
- cb, sb = math.cos(angle * 0.7), math.sin(angle * 0.7)
- projected = []
- depths = []
- for x, y, z in pts:
- x2 = x * ca - z * sa
- z2 = x * sa + z * ca
- y2 = y * cb - z2 * sb
- z3 = y * sb + z2 * cb
- f = 500 / (z3 + 800)
- px = x2 * f + W2
- py = y2 * f + H2
- projected.append((px, py, z3))
- depths.append(z3)
- min_depth = min(depths)
- max_depth = max(depths)
- for i, j in line_segments_cache:
- x1, y1, z1 = projected[i]
- x2, y2, z2 = projected[j]
- depth_t = (z1 + z2) / 2
- cache_key = (depth(depth_t), min_depth, max_depth)
- try:
- rgb, width = color_cache[cache_key]
- except:
- get_color_for_depth(depth_t, min_depth, max_depth)
- rgb, width = color_cache[cache_key]
- canvas.create_line(x1, y1, x2, y2, fill=rgb, width=w)
- canvas.create_oval(x1-w2, y1-w2, x1+w2, y1+w2, outline='', fill=rgb)
- angle += 0.1
- root.after(1, draw)
- draw()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment