Add Separating Axis Theorum demo
This commit is contained in:
		
							
								
								
									
										77
									
								
								geom/demos/sat.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								geom/demos/sat.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
from ..geom import Rect, Polygon
 | 
			
		||||
from .. import WIDTH, HEIGHT, get_cursor_pos
 | 
			
		||||
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 render(self, surface):
 | 
			
		||||
        self.shape2.set_position(*get_cursor_pos())
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
        collisions = []
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
            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.shape1.draw(surface, YELLOW, 4)
 | 
			
		||||
        self.shape2.draw(surface, RED if all(collisions) else WHITE, 4)
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import pygame
 | 
			
		||||
from .demos import aabb, vec_proj
 | 
			
		||||
from .demos import aabb, vec_proj, sat
 | 
			
		||||
from . import HEIGHT
 | 
			
		||||
from .colors import *
 | 
			
		||||
from .draw import text_screen
 | 
			
		||||
@ -11,6 +11,7 @@ class Screen:
 | 
			
		||||
            vec_proj.VecProj(),
 | 
			
		||||
            aabb.AABBDistance(),
 | 
			
		||||
            aabb.PointAABBDistance(),
 | 
			
		||||
            sat.SeparatingAxisTheorem(),
 | 
			
		||||
        ]
 | 
			
		||||
        self.demo = 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user