here2share

# tk_Lissajous_Curve.py

May 8th, 2026
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.48 KB | None | 0 0
  1. # tk_Lissajous_Curve.py
  2.  
  3. import tkinter as tk
  4. import math
  5.  
  6. WIDTH, HEIGHT = 500, 500
  7. W2, H2 = WIDTH//2, HEIGHT//2
  8. STEPS = 200
  9. A = B = C = 180
  10. a, b, c = 3, 4, 5
  11. dx, dy, dz = 0.0, math.pi / 2, math.pi / 3
  12.  
  13. root = tk.Tk()
  14. root.title("Lissajous Curve")
  15.  
  16. root.geometry("+-5+0")
  17. canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="black", highlightthickness=0)
  18. canvas.pack()
  19.  
  20. color_cache = {}
  21. line_segments_cache = []
  22.  
  23. def rgb_to_hex(r, g, b):
  24.     return f"#{r:02x}{g:02x}{b:02x}"
  25.  
  26. def precompute_line_segments():
  27.     global line_segments_cache
  28.     line_segments_cache = [(i, i + 1) for i in range(STEPS)]
  29.  
  30. precompute_line_segments()
  31.  
  32. def depth(depth_t):
  33.     return round(depth_t * 100) / 100
  34.  
  35. def get_color_for_depth(depth_t, min_depth, max_depth):
  36.     quantized_depth = depth(depth_t)
  37.    
  38.     cache_key = (quantized_depth, min_depth, max_depth)
  39.    
  40.     if cache_key in color_cache:
  41.         return color_cache[cache_key]
  42.    
  43.     if max_depth > min_depth:
  44.         norm_depth = 1.0 - (depth_t - min_depth) / (max_depth - min_depth)
  45.         norm_depth = max(0, min(1, norm_depth))
  46.     else:
  47.         norm_depth = 0.5
  48.    
  49.     r = int(0 + norm_depth * 136)
  50.     g = int(51 + norm_depth * 204)
  51.     b = int(102 + norm_depth * 153)
  52.    
  53.     width = max(2, int(5 * norm_depth))
  54.    
  55.     color_cache[cache_key] = (rgb_to_hex(r, g, b), width)
  56.  
  57. pts = []
  58. for i in range(STEPS + 1):
  59.     t = 2 * math.pi * i / STEPS
  60.     x = A * math.sin(a * t + dx)
  61.     y = B * math.sin(b * t + dy)
  62.     z = C * math.sin(c * t + dz)
  63.     pts.append((x, y, z))
  64.  
  65. angle = 0.0
  66. w = 21
  67. w2 = w // 2
  68. def draw():
  69.     global angle
  70.     canvas.delete("all")
  71.     ca, sa = math.cos(angle), math.sin(angle)
  72.     cb, sb = math.cos(angle * 0.7), math.sin(angle * 0.7)
  73.  
  74.     projected = []
  75.     depths = []
  76.    
  77.     for x, y, z in pts:
  78.         x2 = x * ca - z * sa
  79.         z2 = x * sa + z * ca
  80.         y2 = y * cb - z2 * sb
  81.         z3 = y * sb + z2 * cb
  82.        
  83.         f = 500 / (z3 + 800)
  84.         px = x2 * f + W2
  85.         py = y2 * f + H2
  86.         projected.append((px, py, z3))
  87.         depths.append(z3)
  88.     min_depth = min(depths)
  89.     max_depth = max(depths)
  90.  
  91.     for i, j in line_segments_cache:
  92.         x1, y1, z1 = projected[i]
  93.         x2, y2, z2 = projected[j]
  94.        
  95.         depth_t = (z1 + z2) / 2
  96.         cache_key = (depth(depth_t), min_depth, max_depth)
  97.         try:
  98.             rgb, width = color_cache[cache_key]
  99.         except:
  100.             get_color_for_depth(depth_t, min_depth, max_depth)
  101.             rgb, width = color_cache[cache_key]
  102.        
  103.         canvas.create_line(x1, y1, x2, y2, fill=rgb, width=w)
  104.         canvas.create_oval(x1-w2, y1-w2, x1+w2, y1+w2, outline='', fill=rgb)
  105.  
  106.     angle += 0.1
  107.     root.after(1, draw)
  108.  
  109. draw()
  110. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment