from ..geom import Rect, Polygon from .. import WIDTH, HEIGHT, get_cursor_pos, get_inputs from ..colors import * from ..math import * from ..draw import * class SeparatingAxisTheorem: title = "Separating Axis Theorem" def __init__(self): self.shape1 = Polygon(0, 0, [ (0, 60), (60, 0), (0, -60), (-60, 0) ]) self.shape2 = Polygon(*get_cursor_pos(), [ (60, 60), (60, -60), (-60, -60), (-60, 60) ]) def handle_input(self): self.shape2.set_position(*get_cursor_pos()) inputs = get_inputs() if inputs[pygame.K_q]: self.shape2.rotate((1/60) * -90) if inputs[pygame.K_e]: self.shape2.rotate((1/60) * 90) def draw_axis(self, surface, normal, colliding, min1, max1, min2, max2): offset = scale(*rnormal(*normal), 300) # axis line(surface, WHITE, add(*scale(*reverse(*normal), 1000), *offset), add(*scale(*normal, 1000), *offset)) # shape 1 line(surface, GREEN if not colliding else RED, add(*scale(*normal, min1), *offset), add(*scale(*normal, max1), *offset), 8) # shape 2 line(surface, GREEN if not colliding else RED, add(*scale(*normal, min2), *offset), add(*scale(*normal, max2), *offset), 8) def render(self, surface): self.handle_input() normals = [] def add_if_not_exists(normal): for existing in normals: if is_equal(*existing, *normal): return normals.append(normal) for normal in self.shape1.get_normals() + self.shape2.get_normals(): add_if_not_exists(normal) def get_min_max(normal, vertices): _min = float('inf') _max = float('-inf') for vertex in vertices: proj = dot(*normal, *vertex) _min = min(_min, proj) _max = max(_max, proj) return _min, _max overlaps = [] for normal in normals: min1, max1 = get_min_max(normal, self.shape1.get_translated_vertices()) min2, max2 = get_min_max(normal, self.shape2.get_translated_vertices()) overlap = max(min2 - max1, min1 - max2) overlaps.append(overlap) self.draw_axis(surface, normal, overlap < 0, min1, max1, min2, max2) colliding = all(overlap < 0 for overlap in overlaps) if colliding: text_screen(surface, WHITE, (10, HEIGHT - 20), f"Min Distance to Resolve: {max(overlaps)}") self.shape1.draw(surface, YELLOW, 4) self.shape2.draw(surface, RED if colliding else WHITE, 4)