Refactors

- Move all pygame draw calls into draw module
- Scrap indvidual shape modules for single 'geom' module
- Center of screen is now 0,0
This commit is contained in:
Matt Low 2020-11-14 21:15:47 +04:00
parent 699acd1602
commit c313b3e8ba
8 changed files with 129 additions and 53 deletions

View File

@ -11,10 +11,6 @@ def main():
elapsed = 0 elapsed = 0
while geom.loop(): while geom.loop():
clock.tick(60) clock.tick(60)
#elapsed += clock.get_time()
#if elapsed >= 1000:
# print(f"FPS: {clock.get_fps()}")
# elapsed = 0
pygame.quit() pygame.quit()
sys.exit() sys.exit()

View File

@ -1,6 +1,5 @@
import pygame import pygame
from pygame.locals import * from .math import sub
from . import text
WIDTH = 1280 WIDTH = 1280
HEIGHT = 720 HEIGHT = 720
@ -12,18 +11,21 @@ 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)
pygame.key.set_repeat(500, 60)
global surface global surface
global screen global screen
surface = pygame.display.set_mode((WIDTH, HEIGHT)) surface = pygame.display.set_mode((WIDTH, HEIGHT))
text.init()
from . import draw
draw.init()
from .screen import Screen from .screen import Screen
screen = Screen() screen = Screen()
def loop(): def loop():
for event in pygame.event.get(QUIT): for event in pygame.event.get(pygame.QUIT):
return False return False
surface.fill((0, 0, 0)) surface.fill((0, 0, 0))
@ -32,3 +34,6 @@ def loop():
pygame.display.update() pygame.display.update()
return True return True
def get_cursor_pos():
return sub(*pygame.mouse.get_pos(), WIDTH / 2, HEIGHT / 2)

View File

@ -1,9 +1,9 @@
from pygame import draw, mouse from pygame import draw
from .. import text from ..geom import Rect
from ..geom.rect import Rect from .. import WIDTH, HEIGHT, get_cursor_pos
from .. import WIDTH, HEIGHT, text
from ..colors import * from ..colors import *
from ..math import * from ..math import *
from ..draw import *
class AABBDistance: class AABBDistance:
@ -11,13 +11,13 @@ class AABBDistance:
def render(self, surface): def render(self, surface):
rect_a = Rect( rect_a = Rect(
WIDTH / 2 - (WIDTH / 8), -(WIDTH / 8),
HEIGHT / 2 - (HEIGHT / 8), -(HEIGHT / 8),
WIDTH / 4, WIDTH / 4,
HEIGHT / 4, HEIGHT / 4,
) )
rect_b = Rect( rect_b = Rect(
*mouse.get_pos(), *get_cursor_pos(),
WIDTH / 5, WIDTH / 5,
HEIGHT / 5 HEIGHT / 5
) )
@ -41,10 +41,10 @@ class AABBDistance:
else: else:
distance = length(gap_x, gap_y) distance = length(gap_x, gap_y)
text.draw(surface, (10, HEIGHT - 20), WHITE, f"Distance: {distance}") text_screen(surface, WHITE, (10, HEIGHT - 20), f"Distance: {distance}")
rect_a.draw(surface, YELLOW, 4) rect_a.draw(surface, YELLOW, 4)
rect_b.draw(surface, WHITE, 4) rect_b.draw(surface, WHITE, 4)
draw.line(surface, RED if distance < 0 else GREEN, line(surface, RED if distance < 0 else GREEN,
rect_a.get_center(), rect_b.get_center(), 2) rect_a.get_center(), rect_b.get_center(), 2)
class PointAABBDistance: class PointAABBDistance:
@ -53,12 +53,12 @@ class PointAABBDistance:
def render(self, surface): def render(self, surface):
rect_a = Rect( rect_a = Rect(
WIDTH / 2 - (WIDTH / 8), -(WIDTH / 8),
HEIGHT / 2 - (HEIGHT / 8), -(HEIGHT / 8),
WIDTH / 4, WIDTH / 4,
HEIGHT / 4, HEIGHT / 4,
) )
cx, cy = mouse.get_pos() cx, cy = get_cursor_pos()
# cx, cy = point # cx, cy = point
dist_x = abs(cx - rect_a.cx) dist_x = abs(cx - rect_a.cx)
@ -79,7 +79,7 @@ class PointAABBDistance:
else: else:
distance = length(gap_x, gap_y) distance = length(gap_x, gap_y)
text.draw(surface, (10, HEIGHT - 20), WHITE, f"Distance: {distance}") text_screen(surface, WHITE, (10, HEIGHT - 20), f"Distance: {distance}")
rect_a.draw(surface, YELLOW, 4) rect_a.draw(surface, YELLOW, 4)
draw.line(surface, RED if distance < 0 else GREEN, line(surface, RED if distance < 0 else GREEN,
rect_a.get_center(), (cx, cy), 2) rect_a.get_center(), (cx, cy), 2)

View File

@ -1,19 +1,19 @@
from pygame import draw, mouse from .. import HEIGHT, WIDTH, get_cursor_pos
from .. import HEIGHT, WIDTH
from ..colors import * from ..colors import *
from ..math import * from ..math import *
from ..draw import *
class VecProj: class VecProj:
title = "Vector Projection" title = "Vector Projection"
def render(self, surface): def render(self, surface):
x1 = WIDTH / 4 x1 = -(WIDTH / 4)
y1 = HEIGHT / 2 + 100 y1 = 100
x2 = 0.75 * WIDTH x2 = WIDTH / 4
y2 = HEIGHT / 2 y2 = 0
cx, cy = mouse.get_pos() cx, cy = get_cursor_pos()
lx, ly = x2 - x1, y2 - y1 # line vector lx, ly = x2 - x1, y2 - y1 # line vector
llen = length(lx, ly) llen = length(lx, ly)
@ -21,9 +21,9 @@ class VecProj:
lcx, lcy = cx - x1, cy - y1 # line start - cursor vector lcx, lcy = cx - x1, cy - y1 # line start - cursor vector
proj = dot(lcx, lcy, lx, ly) / llen proj = dot(lcx, lcy, lx, ly) / llen
nearest_point = add(x1, y1, *scale(lnx, lny, proj))
draw.line( line(surface, GREEN, (cx, cy), nearest_point, 5)
surface, GREEN, (cx, cy), add(x1, y1, *scale(lnx, lny, proj)), 5 line(surface, WHITE, (cx, cy), (x1, y1), 5)
) line(surface, YELLOW, (x1, y1), (x2, y2), 5)
draw.line(surface, WHITE, (cx, cy), (x1, y1), 5) line(surface, RED, (x1, y1), nearest_point, 5)
draw.line(surface, YELLOW, (x1, y1), (x2, y2), 5)

41
geom/draw.py Normal file
View File

@ -0,0 +1,41 @@
import pygame
from pygame import gfxdraw
from pygame import freetype
from . import HEIGHT, WIDTH
from .math import add
OFFSET = (WIDTH/2, HEIGHT/2)
FONT = None
def init():
global FONT
freetype.init()
FONT = freetype.SysFont('Arial', 16)
def line(surface, color, start, end, width=0):
pygame.draw.line(surface, color,
add(*OFFSET, *start), add(*OFFSET, *end), width)
def polygon(surface, color, vertices, width):
translated = [add(*OFFSET, *vertex) for vertex in vertices]
pygame.draw.polygon(surface, color, translated, width)
def rect(surface, color, x, y, height, width, stroke_width):
pygame.draw.rect(surface, color,
pygame.Rect(OFFSET[0] + x, OFFSET[1] + y, height, width),
stroke_width)
def pixel(surface, color, x, y):
gfxdraw.pixel(surface,
int(OFFSET[0] + x),
int(OFFSET[1] + y),
color)
def text(surface, color, position, text):
FONT.render_to(surface, add(*OFFSET, *position), text, color)
def text_screen(surface, color, position, text):
FONT.render_to(surface, position, text, color)

View File

@ -1,5 +1,5 @@
from pygame import draw, gfxdraw from .math import *
from pygame.rect import Rect as pRect from .draw import *
class Rect: class Rect:
@ -49,7 +49,50 @@ class Rect:
and y >= self.min_y and y <= self.max_y) and y >= self.min_y and y <= self.max_y)
def draw(self, surface, colour, width): def draw(self, surface, colour, width):
#gfxdraw.pixel(surface, *self.get_center_px(), colour) pixel(surface, colour, *self.get_center())
draw.rect(surface, colour, rect(surface, colour, self.x, self.y, self.width, self.height, width)
pRect(self.x, self.y, self.width, self.height),
width) class Polygon:
def __init__(self, x, y, vertices, origin_x=0, origin_y=0):
self.x = x
self.y = y
self.vertices = vertices
self.origin_x = origin_x
self.origin_y = origin_y
self.update()
def update(self):
self.translated_vertices = [
(self.x + self.origin_x + x,
self.y + self.origin_y + y)
for x, y in self.vertices
]
def set_position(self, x, y):
self.x = x
self.y = y
self.update()
def get_normals(self):
return [
normalize(*lnormal(*sub(*v2, *v1)))
for v1, v2 in self.get_segments()
]
def get_translated_vertices(self):
return self.translated_vertices
def get_segments(self):
cnt = len(self.vertices)
return [
(
self.translated_vertices[i],
self.translated_vertices[i + 1 if i + 1 < cnt else 0],
)
for i in range(cnt)
]
def draw(self, surface, colour, width):
polygon(surface, colour, self.translated_vertices, width)
pixel(surface, colour, self.x, self.y)

View File

@ -1,7 +1,8 @@
import pygame import pygame
from .demos import aabb, vec_proj from .demos import aabb, vec_proj
from . import text, HEIGHT from . import HEIGHT
from .colors import * from .colors import *
from .draw import text_screen
class Screen: class Screen:
@ -27,9 +28,9 @@ class Screen:
def draw_demo_list(self, surface): def draw_demo_list(self, surface):
y_offset = 10 y_offset = 10
for i in range(len(self.demos)): for i in range(len(self.demos)):
text.draw(surface, text_screen(surface,
(10, y_offset + i * 20),
CYAN if self.demo == i else WHITE, CYAN if self.demo == i else WHITE,
(10, y_offset + i * 20),
self.demos[i].title) self.demos[i].title)
def render(self, surface): def render(self, surface):

View File

@ -1,10 +0,0 @@
from pygame import freetype
FONT = None
def init():
global FONT
FONT = freetype.SysFont('Arial', 16)
def draw(surface, position, color, text):
FONT.render_to(surface, position, text, color)