here2share

# tk_triangle_cache.py

Aug 30th, 2025 (edited)
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.13 KB | None | 0 0
  1. # tk_triangle_cache.py
  2.  
  3. import tkinter as tk
  4. import math
  5.  
  6. root = tk.Tk()
  7. root.geometry("600x600+0+0")
  8. root.title("Ultra-Fast Triangle Collision Detection")
  9.  
  10. canvas = tk.Canvas(root, width=600, height=600, bg='black')
  11. canvas.pack()
  12.  
  13. tri1 = [200, 300, 45]
  14. tri2 = [400, 350, 0]
  15.  
  16. drag_state = {'active': False, 'triangle': None, 'offset_x': 0, 'offset_y': 0}
  17.  
  18. ANGLE_STEPS = 360
  19. SIZE = 180
  20.  
  21. SIN_TABLE = [math.sin(i * 2 * math.pi / ANGLE_STEPS) for i in range(ANGLE_STEPS)]
  22. COS_TABLE = [math.cos(i * 2 * math.pi / ANGLE_STEPS) for i in range(ANGLE_STEPS)]
  23.  
  24. TRIANGLE_VERTICES = []
  25. for angle_idx in range(ANGLE_STEPS):
  26.     cos_a = COS_TABLE[angle_idx]
  27.     sin_a = SIN_TABLE[angle_idx]
  28.    
  29.     base_points = [
  30.         (0, -SIZE * 0.67),
  31.         (-SIZE * 0.58, SIZE * 0.33),
  32.         (SIZE * 0.58, SIZE * 0.33)
  33.     ]
  34.    
  35.     rotated = []
  36.     for px, py in base_points:
  37.         rx = px * cos_a - py * sin_a
  38.         ry = px * sin_a + py * cos_a
  39.         rotated.append((rx, ry))
  40.    
  41.     TRIANGLE_VERTICES.append(rotated)
  42.  
  43. TRIANGLE_NORMALS = []
  44. for vertices in TRIANGLE_VERTICES:
  45.     edges = []
  46.     for i in range(3):
  47.         j = (i + 1) % 3
  48.         edge = (vertices[j][0] - vertices[i][0], vertices[j][1] - vertices[i][1])
  49.         edges.append(edge)
  50.    
  51.     normals = []
  52.     for edge in edges:
  53.         normal = (-edge[1], edge[0])
  54.         length = math.sqrt(normal[0]**2 + normal[1]**2)
  55.         if length > 0:
  56.             normal = (normal[0]/length, normal[1]/length)
  57.         normals.append(normal)
  58.     TRIANGLE_NORMALS.append(normals)
  59.  
  60. def get_triangle_vertices_fast(center_x, center_y, angle_idx):
  61.     vertices = []
  62.     for rx, ry in TRIANGLE_VERTICES[angle_idx]:
  63.         vertices.append((rx + center_x, ry + center_y))
  64.     return vertices
  65.  
  66. def project_triangle_fast(vertices, axis):
  67.     dot0 = vertices[0][0] * axis[0] + vertices[0][1] * axis[1]
  68.     dot1 = vertices[1][0] * axis[0] + vertices[1][1] * axis[1]
  69.     dot2 = vertices[2][0] * axis[0] + vertices[2][1] * axis[1]
  70.    
  71.     if dot0 <= dot1:
  72.         if dot0 <= dot2:
  73.             min_dot = dot0
  74.             max_dot = dot1 if dot1 >= dot2 else dot2
  75.         else:
  76.             min_dot = dot2
  77.             max_dot = dot1
  78.     else:
  79.         if dot1 <= dot2:
  80.             min_dot = dot1
  81.             max_dot = dot0 if dot0 >= dot2 else dot2
  82.         else:
  83.             min_dot = dot2
  84.             max_dot = dot0
  85.    
  86.     return min_dot, max_dot
  87.  
  88. def sat_collide_check(x1, y1, angle1_idx, x2, y2, angle2_idx):
  89.     vertices1 = get_triangle_vertices_fast(x1, y1, angle1_idx)
  90.     vertices2 = get_triangle_vertices_fast(x2, y2, angle2_idx)
  91.    
  92.     normals1 = TRIANGLE_NORMALS[angle1_idx]
  93.     for normal in normals1:
  94.         min1, max1 = project_triangle_fast(vertices1, normal)
  95.         min2, max2 = project_triangle_fast(vertices2, normal)
  96.        
  97.         if max1 < min2 or max2 < min1:
  98.             return False
  99.    
  100.     normals2 = TRIANGLE_NORMALS[angle2_idx]
  101.     for normal in normals2:
  102.         min1, max1 = project_triangle_fast(vertices1, normal)
  103.         min2, max2 = project_triangle_fast(vertices2, normal)
  104.        
  105.         if max1 < min2 or max2 < min1:
  106.             return False
  107.    
  108.     return True
  109.  
  110. def collide_detect_ultra_fast(x1, y1, angle1_idx, x2, y2, angle2_idx):    
  111.     return sat_collide_check(x1, y1, angle1_idx, x2, y2, angle2_idx)
  112.  
  113. def draw_triangle_fast(x, y, angle_idx, color='white', tag=None):
  114.     vertices = get_triangle_vertices_fast(x, y, angle_idx)
  115.     points = []
  116.     for vx, vy in vertices:
  117.         points.extend([vx, vy])
  118.    
  119.     if tag:
  120.         canvas.delete(tag)
  121.     return canvas.create_polygon(points, outline=color, fill='', width=2, tags=tag)
  122.  
  123. def point_in_triangle(px, py, vertices):
  124.     x1, y1 = vertices[0]
  125.     x2, y2 = vertices[1]
  126.     x3, y3 = vertices[2]
  127.    
  128.     d = (y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3)
  129.     if abs(d) < 1e-10:
  130.         return False
  131.    
  132.     a = ((y2 - y3)*(px - x3) + (x3 - x2)*(py - y3)) / d
  133.     b = ((y3 - y1)*(px - x3) + (x1 - x3)*(py - y3)) / d
  134.     c = 1 - a - b
  135.    
  136.     return 0 <= a <= 1 and 0 <= b <= 1 and 0 <= c <= 1
  137.  
  138. def on_mouse_press(event):
  139.     x, y = event.x, event.y
  140.    
  141.     vertices1 = get_triangle_vertices_fast(tri1[0], tri1[1], tri1[2])
  142.     if point_in_triangle(x, y, vertices1):
  143.         drag_state['active'] = True
  144.         drag_state['triangle'] = 1
  145.         drag_state['offset_x'] = x - tri1[0]
  146.         drag_state['offset_y'] = y - tri1[1]
  147.         return
  148.    
  149.     vertices2 = get_triangle_vertices_fast(tri2[0], tri2[1], tri2[2])
  150.     if point_in_triangle(x, y, vertices2):
  151.         drag_state['active'] = True
  152.         drag_state['triangle'] = 2
  153.         drag_state['offset_x'] = x - tri2[0]
  154.         drag_state['offset_y'] = y - tri2[1]
  155.         return
  156.  
  157. def on_mouse_drag(event):
  158.     if not drag_state['active']:
  159.         return
  160.    
  161.     x, y = event.x, event.y
  162.     new_x = x - drag_state['offset_x']
  163.     new_y = y - drag_state['offset_y']
  164.    
  165.     new_x = max(50, min(550, new_x))
  166.     new_y = max(50, min(550, new_y))
  167.    
  168.     if drag_state['triangle'] == 1:
  169.         tri1[0] = new_x
  170.         tri1[1] = new_y
  171.     elif drag_state['triangle'] == 2:
  172.         tri2[0] = new_x
  173.         tri2[1] = new_y
  174.    
  175. def on_mouse_release(event):
  176.     drag_state['active'] = False
  177.     drag_state['triangle'] = None
  178.  
  179. def on_right_click(event):
  180.     x, y = event.x, event.y
  181.    
  182.     vertices1 = get_triangle_vertices_fast(tri1[0], tri1[1], tri1[2])
  183.     if point_in_triangle(x, y, vertices1):
  184.         tri1[2] = (tri1[2] + 10) % ANGLE_STEPS
  185.         return
  186.    
  187.     vertices2 = get_triangle_vertices_fast(tri2[0], tri2[1], tri2[2])
  188.     if point_in_triangle(x, y, vertices2):
  189.         tri2[2] = (tri2[2] + 10) % ANGLE_STEPS
  190.         return
  191.  
  192. canvas.bind('<Button-1>', on_mouse_press)
  193. canvas.bind('<B1-Motion>', on_mouse_drag)
  194. canvas.bind('<ButtonRelease-1>', on_mouse_release)
  195. canvas.bind('<Button-3>', on_right_click)
  196.  
  197. canvas.focus_set()
  198.  
  199. instructions = [
  200.     "Left click and drag to move triangles",
  201.     "Right click on triangle to rotate 10°",
  202.     "Triangles turn RED when colliding"
  203. ]
  204.  
  205. for i, instruction in enumerate(instructions):
  206.     canvas.create_text(10, 10 + i*15, text=instruction, fill='yellow', font=('Arial', 10), anchor='w')
  207.  
  208. while 1:
  209.     is_collide = collide_detect_ultra_fast(tri1[0], tri1[1], tri1[2], tri2[0], tri2[1], tri2[2])
  210.    
  211.     color = 'red' if is_collide else 'white'
  212.    
  213.     draw_triangle_fast(tri1[0], tri1[1], tri1[2], color, 'tri1')
  214.     draw_triangle_fast(tri2[0], tri2[1], tri2[2], color, 'tri2')
  215.    
  216.     canvas.delete('status')
  217.     status_text = "COLLISION!" if is_collide else "No Collision Detected"
  218.     canvas.create_text(300, 100, text=status_text, fill=color, font=('Arial', 16), tags='status')
  219.    
  220.     canvas.delete('i')
  221.     angle1_deg = tri1[2] * 360 // ANGLE_STEPS
  222.     angle2_deg = tri2[2] * 360 // ANGLE_STEPS
  223.     i1 = f"Triangle 1: ({tri1[0]}, {tri1[1]}, {angle1_deg}°)"
  224.     i2 = f"Triangle 2: ({tri2[0]}, {tri2[1]}, {angle2_deg}°)"
  225.     canvas.create_text(10, 570, text=i1, fill='cyan', font=('Arial', 10), anchor='w', tags='i')
  226.     canvas.create_text(10, 585, text=i2, fill='cyan', font=('Arial', 10), anchor='w', tags='i')
  227.  
  228.     root.update()
Advertisement
Add Comment
Please, Sign In to add comment