Skip to content

Instantly share code, notes, and snippets.

@f0ursqu4r3
Created September 12, 2021 13:07
Show Gist options
  • Save f0ursqu4r3/355014ffd3f645ad5548b687ceb09418 to your computer and use it in GitHub Desktop.
Save f0ursqu4r3/355014ffd3f645ad5548b687ceb09418 to your computer and use it in GitHub Desktop.
import pygame
import math
from pygame import Vector2
pygame.init()
def intersect_line(P0, P1, Q0, Q1):
d = (P1[0]-P0[0]) * (Q1[1]-Q0[1]) + (P1[1]-P0[1]) * (Q0[0]-Q1[0])
if d == 0:
return None
t = ((Q0[0]-P0[0]) * (Q1[1]-Q0[1]) + (Q0[1]-P0[1]) * (Q0[0]-Q1[0])) / d
u = ((Q0[0]-P0[0]) * (P1[1]-P0[1]) + (Q0[1]-P0[1]) * (P0[0]-P1[0])) / d
if 0 <= t <= 1 and 0 <= u <= 1:
return Vector2(round(P1[0] * t + P0[0] * (1-t)), round(P1[1] * t + P0[1] * (1-t)))
return None
def find_intersect_points_for_rect(start, end, rect):
intersections = [
intersect_line(start, end, Vector2(rect.left, rect.top), Vector2(rect.right, rect.top)),
intersect_line(start, end, Vector2(rect.right, rect.top), Vector2(rect.right, rect.bottom)),
intersect_line(start, end, Vector2(rect.right, rect.bottom), Vector2(rect.left, rect.bottom)),
intersect_line(start, end, Vector2(rect.left, rect.bottom), Vector2(rect.left, rect.top))
]
return [i for i in intersections if i]
def find_nearest_intersection(start, end, rect):
intersections = find_intersect_points_for_rect(start, end, rect)
if not intersections:
return
return min(intersections, key=lambda i: start.distance_to(i))
disp = pygame.display.set_mode((320, 320))
pygame.display.set_caption('testing')
clock = pygame.time.Clock()
start = Vector2(20, 170)
angle = math.radians(30)
dist = 100
end = Vector2(start.x + math.cos(angle) * dist, start.y + math.sin(angle) * dist)
view = pygame.Rect(60,60,200,200)
while 1:
for event in pygame.event.get():
if (event.type == pygame.QUIT or
(event.type == pygame.KEYDOWN and
event.key == pygame.K_ESCAPE)):
pygame.quit()
quit()
pressed = pygame.mouse.get_pressed(num_buttons=3)
if pressed[0]:
start = Vector2(pygame.mouse.get_pos())
elif pressed[2]:
end = Vector2(pygame.mouse.get_pos())
disp.fill((30, 20, 30))
pygame.draw.rect(disp, (100,)*3, view, 1)
pygame.draw.line(disp, (100, 0, 0), start, end)
if intersection := find_nearest_intersection(start, end, view):
pygame.draw.circle(disp, (0, 200, 0), intersection, 2)
pygame.draw.circle(disp, (0, 200, 200), start, 3)
pygame.draw.circle(disp, (200, 0, 200), end, 3)
pygame.display.flip()
clock.tick(60)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment