Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_triangle_cache.py
- import tkinter as tk
- import math
- root = tk.Tk()
- root.geometry("600x600+0+0")
- root.title("Ultra-Fast Triangle Collision Detection")
- canvas = tk.Canvas(root, width=600, height=600, bg='black')
- canvas.pack()
- tri1 = [200, 300, 45]
- tri2 = [400, 350, 0]
- drag_state = {'active': False, 'triangle': None, 'offset_x': 0, 'offset_y': 0}
- ANGLE_STEPS = 360
- SIZE = 180
- SIN_TABLE = [math.sin(i * 2 * math.pi / ANGLE_STEPS) for i in range(ANGLE_STEPS)]
- COS_TABLE = [math.cos(i * 2 * math.pi / ANGLE_STEPS) for i in range(ANGLE_STEPS)]
- TRIANGLE_VERTICES = []
- for angle_idx in range(ANGLE_STEPS):
- cos_a = COS_TABLE[angle_idx]
- sin_a = SIN_TABLE[angle_idx]
- base_points = [
- (0, -SIZE * 0.67),
- (-SIZE * 0.58, SIZE * 0.33),
- (SIZE * 0.58, SIZE * 0.33)
- ]
- rotated = []
- for px, py in base_points:
- rx = px * cos_a - py * sin_a
- ry = px * sin_a + py * cos_a
- rotated.append((rx, ry))
- TRIANGLE_VERTICES.append(rotated)
- TRIANGLE_NORMALS = []
- for vertices in TRIANGLE_VERTICES:
- edges = []
- for i in range(3):
- j = (i + 1) % 3
- edge = (vertices[j][0] - vertices[i][0], vertices[j][1] - vertices[i][1])
- edges.append(edge)
- normals = []
- for edge in edges:
- normal = (-edge[1], edge[0])
- length = math.sqrt(normal[0]**2 + normal[1]**2)
- if length > 0:
- normal = (normal[0]/length, normal[1]/length)
- normals.append(normal)
- TRIANGLE_NORMALS.append(normals)
- def get_triangle_vertices_fast(center_x, center_y, angle_idx):
- vertices = []
- for rx, ry in TRIANGLE_VERTICES[angle_idx]:
- vertices.append((rx + center_x, ry + center_y))
- return vertices
- def project_triangle_fast(vertices, axis):
- dot0 = vertices[0][0] * axis[0] + vertices[0][1] * axis[1]
- dot1 = vertices[1][0] * axis[0] + vertices[1][1] * axis[1]
- dot2 = vertices[2][0] * axis[0] + vertices[2][1] * axis[1]
- if dot0 <= dot1:
- if dot0 <= dot2:
- min_dot = dot0
- max_dot = dot1 if dot1 >= dot2 else dot2
- else:
- min_dot = dot2
- max_dot = dot1
- else:
- if dot1 <= dot2:
- min_dot = dot1
- max_dot = dot0 if dot0 >= dot2 else dot2
- else:
- min_dot = dot2
- max_dot = dot0
- return min_dot, max_dot
- def sat_collide_check(x1, y1, angle1_idx, x2, y2, angle2_idx):
- vertices1 = get_triangle_vertices_fast(x1, y1, angle1_idx)
- vertices2 = get_triangle_vertices_fast(x2, y2, angle2_idx)
- normals1 = TRIANGLE_NORMALS[angle1_idx]
- for normal in normals1:
- min1, max1 = project_triangle_fast(vertices1, normal)
- min2, max2 = project_triangle_fast(vertices2, normal)
- if max1 < min2 or max2 < min1:
- return False
- normals2 = TRIANGLE_NORMALS[angle2_idx]
- for normal in normals2:
- min1, max1 = project_triangle_fast(vertices1, normal)
- min2, max2 = project_triangle_fast(vertices2, normal)
- if max1 < min2 or max2 < min1:
- return False
- return True
- def collide_detect_ultra_fast(x1, y1, angle1_idx, x2, y2, angle2_idx):
- return sat_collide_check(x1, y1, angle1_idx, x2, y2, angle2_idx)
- def draw_triangle_fast(x, y, angle_idx, color='white', tag=None):
- vertices = get_triangle_vertices_fast(x, y, angle_idx)
- points = []
- for vx, vy in vertices:
- points.extend([vx, vy])
- if tag:
- canvas.delete(tag)
- return canvas.create_polygon(points, outline=color, fill='', width=2, tags=tag)
- def point_in_triangle(px, py, vertices):
- x1, y1 = vertices[0]
- x2, y2 = vertices[1]
- x3, y3 = vertices[2]
- d = (y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3)
- if abs(d) < 1e-10:
- return False
- a = ((y2 - y3)*(px - x3) + (x3 - x2)*(py - y3)) / d
- b = ((y3 - y1)*(px - x3) + (x1 - x3)*(py - y3)) / d
- c = 1 - a - b
- return 0 <= a <= 1 and 0 <= b <= 1 and 0 <= c <= 1
- def on_mouse_press(event):
- x, y = event.x, event.y
- vertices1 = get_triangle_vertices_fast(tri1[0], tri1[1], tri1[2])
- if point_in_triangle(x, y, vertices1):
- drag_state['active'] = True
- drag_state['triangle'] = 1
- drag_state['offset_x'] = x - tri1[0]
- drag_state['offset_y'] = y - tri1[1]
- return
- vertices2 = get_triangle_vertices_fast(tri2[0], tri2[1], tri2[2])
- if point_in_triangle(x, y, vertices2):
- drag_state['active'] = True
- drag_state['triangle'] = 2
- drag_state['offset_x'] = x - tri2[0]
- drag_state['offset_y'] = y - tri2[1]
- return
- def on_mouse_drag(event):
- if not drag_state['active']:
- return
- x, y = event.x, event.y
- new_x = x - drag_state['offset_x']
- new_y = y - drag_state['offset_y']
- new_x = max(50, min(550, new_x))
- new_y = max(50, min(550, new_y))
- if drag_state['triangle'] == 1:
- tri1[0] = new_x
- tri1[1] = new_y
- elif drag_state['triangle'] == 2:
- tri2[0] = new_x
- tri2[1] = new_y
- def on_mouse_release(event):
- drag_state['active'] = False
- drag_state['triangle'] = None
- def on_right_click(event):
- x, y = event.x, event.y
- vertices1 = get_triangle_vertices_fast(tri1[0], tri1[1], tri1[2])
- if point_in_triangle(x, y, vertices1):
- tri1[2] = (tri1[2] + 10) % ANGLE_STEPS
- return
- vertices2 = get_triangle_vertices_fast(tri2[0], tri2[1], tri2[2])
- if point_in_triangle(x, y, vertices2):
- tri2[2] = (tri2[2] + 10) % ANGLE_STEPS
- return
- canvas.bind('<Button-1>', on_mouse_press)
- canvas.bind('<B1-Motion>', on_mouse_drag)
- canvas.bind('<ButtonRelease-1>', on_mouse_release)
- canvas.bind('<Button-3>', on_right_click)
- canvas.focus_set()
- instructions = [
- "Left click and drag to move triangles",
- "Right click on triangle to rotate 10°",
- "Triangles turn RED when colliding"
- ]
- for i, instruction in enumerate(instructions):
- canvas.create_text(10, 10 + i*15, text=instruction, fill='yellow', font=('Arial', 10), anchor='w')
- while 1:
- is_collide = collide_detect_ultra_fast(tri1[0], tri1[1], tri1[2], tri2[0], tri2[1], tri2[2])
- color = 'red' if is_collide else 'white'
- draw_triangle_fast(tri1[0], tri1[1], tri1[2], color, 'tri1')
- draw_triangle_fast(tri2[0], tri2[1], tri2[2], color, 'tri2')
- canvas.delete('status')
- status_text = "COLLISION!" if is_collide else "No Collision Detected"
- canvas.create_text(300, 100, text=status_text, fill=color, font=('Arial', 16), tags='status')
- canvas.delete('i')
- angle1_deg = tri1[2] * 360 // ANGLE_STEPS
- angle2_deg = tri2[2] * 360 // ANGLE_STEPS
- i1 = f"Triangle 1: ({tri1[0]}, {tri1[1]}, {angle1_deg}°)"
- i2 = f"Triangle 2: ({tri2[0]}, {tri2[1]}, {angle2_deg}°)"
- canvas.create_text(10, 570, text=i1, fill='cyan', font=('Arial', 10), anchor='w', tags='i')
- canvas.create_text(10, 585, text=i2, fill='cyan', font=('Arial', 10), anchor='w', tags='i')
- root.update()
Advertisement
Add Comment
Please, Sign In to add comment