Allow rotating shape in SAT
Moved rendering of separating axes to function Calculate overlaps instead of binary collision, write min distance to resolve collision
This commit is contained in:
parent
3296d3a582
commit
5dfd84a2f6
@ -7,7 +7,6 @@ HEIGHT = 720
|
||||
surface = None
|
||||
screen = None
|
||||
|
||||
|
||||
def init():
|
||||
pygame.display.set_caption("Geom Demo")
|
||||
pygame.mouse.set_visible(False)
|
||||
@ -37,3 +36,6 @@ def loop():
|
||||
|
||||
def get_cursor_pos():
|
||||
return sub(*pygame.mouse.get_pos(), WIDTH / 2, HEIGHT / 2)
|
||||
|
||||
def get_inputs():
|
||||
return pygame.key.get_pressed()
|
||||
|
@ -1,9 +1,10 @@
|
||||
from ..geom import Rect, Polygon
|
||||
from .. import WIDTH, HEIGHT, get_cursor_pos
|
||||
from .. import WIDTH, HEIGHT, get_cursor_pos, get_inputs
|
||||
from ..colors import *
|
||||
from ..math import *
|
||||
from ..draw import *
|
||||
|
||||
|
||||
class SeparatingAxisTheorem:
|
||||
|
||||
title = "Separating Axis Theorem"
|
||||
@ -23,9 +24,35 @@ class SeparatingAxisTheorem:
|
||||
(-60, 60)
|
||||
])
|
||||
|
||||
def render(self, surface):
|
||||
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, YELLOW if not colliding else RED,
|
||||
add(*scale(*normal, min1), *offset),
|
||||
add(*scale(*normal, max1), *offset), 5)
|
||||
# shape 2
|
||||
line(surface, YELLOW if not colliding else RED,
|
||||
add(*scale(*normal, min2), *offset),
|
||||
add(*scale(*normal, max2), *offset), 5)
|
||||
|
||||
def render(self, surface):
|
||||
self.handle_input()
|
||||
|
||||
normals = []
|
||||
|
||||
def add_if_not_exists(normal):
|
||||
@ -46,32 +73,22 @@ class SeparatingAxisTheorem:
|
||||
_max = max(_max, proj)
|
||||
return _min, _max
|
||||
|
||||
collisions = []
|
||||
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())
|
||||
|
||||
colliding = max1 > min2 and max2 > min1
|
||||
collisions.append(colliding)
|
||||
overlap = max(min2 - max1, min1 - max2)
|
||||
overlaps.append(overlap)
|
||||
|
||||
offset = scale(*rnormal(*normal), 300)
|
||||
|
||||
# axis
|
||||
line(surface, WHITE,
|
||||
add(*scale(*reverse(*normal), 1000), *offset),
|
||||
add(*scale(*normal, 1000), *offset))
|
||||
|
||||
# shape 1
|
||||
line(surface, YELLOW if not colliding else RED,
|
||||
add(*scale(*normal, min1), *offset),
|
||||
add(*scale(*normal, max1), *offset), 5)
|
||||
# shape 2
|
||||
line(surface, YELLOW if not colliding else RED,
|
||||
add(*scale(*normal, min2), *offset),
|
||||
add(*scale(*normal, max2), *offset), 5)
|
||||
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 all(collisions) else WHITE, 4)
|
||||
self.shape2.draw(surface, RED if colliding else WHITE, 4)
|
||||
|
Loading…
Reference in New Issue
Block a user