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
|
surface = None
|
||||||
screen = None
|
screen = None
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
pygame.display.set_caption("Geom Demo")
|
pygame.display.set_caption("Geom Demo")
|
||||||
pygame.mouse.set_visible(False)
|
pygame.mouse.set_visible(False)
|
||||||
@ -37,3 +36,6 @@ def loop():
|
|||||||
|
|
||||||
def get_cursor_pos():
|
def get_cursor_pos():
|
||||||
return sub(*pygame.mouse.get_pos(), WIDTH / 2, HEIGHT / 2)
|
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 ..geom import Rect, Polygon
|
||||||
from .. import WIDTH, HEIGHT, get_cursor_pos
|
from .. import WIDTH, HEIGHT, get_cursor_pos, get_inputs
|
||||||
from ..colors import *
|
from ..colors import *
|
||||||
from ..math import *
|
from ..math import *
|
||||||
from ..draw import *
|
from ..draw import *
|
||||||
|
|
||||||
|
|
||||||
class SeparatingAxisTheorem:
|
class SeparatingAxisTheorem:
|
||||||
|
|
||||||
title = "Separating Axis Theorem"
|
title = "Separating Axis Theorem"
|
||||||
@ -23,9 +24,35 @@ class SeparatingAxisTheorem:
|
|||||||
(-60, 60)
|
(-60, 60)
|
||||||
])
|
])
|
||||||
|
|
||||||
def render(self, surface):
|
def handle_input(self):
|
||||||
self.shape2.set_position(*get_cursor_pos())
|
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 = []
|
normals = []
|
||||||
|
|
||||||
def add_if_not_exists(normal):
|
def add_if_not_exists(normal):
|
||||||
@ -46,32 +73,22 @@ class SeparatingAxisTheorem:
|
|||||||
_max = max(_max, proj)
|
_max = max(_max, proj)
|
||||||
return _min, _max
|
return _min, _max
|
||||||
|
|
||||||
collisions = []
|
overlaps = []
|
||||||
for normal in normals:
|
for normal in normals:
|
||||||
min1, max1 = get_min_max(normal,
|
min1, max1 = get_min_max(normal,
|
||||||
self.shape1.get_translated_vertices())
|
self.shape1.get_translated_vertices())
|
||||||
min2, max2 = get_min_max(normal,
|
min2, max2 = get_min_max(normal,
|
||||||
self.shape2.get_translated_vertices())
|
self.shape2.get_translated_vertices())
|
||||||
|
|
||||||
colliding = max1 > min2 and max2 > min1
|
overlap = max(min2 - max1, min1 - max2)
|
||||||
collisions.append(colliding)
|
overlaps.append(overlap)
|
||||||
|
|
||||||
offset = scale(*rnormal(*normal), 300)
|
self.draw_axis(surface, normal, overlap < 0, min1, max1, min2, max2)
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
|
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.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