Windspar

Pygame Ray Intersect Line

Jun 25th, 2021
1,554
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.42 KB | None | 0 0
  1. # Ray Intersect Line
  2. import pygame
  3.  
  4. class Line:
  5.     def __init__(self, x1, y1, x2, y2, color, width=1):
  6.         self.a = pygame.Vector2(x1, y1)
  7.         self.b = pygame.Vector2(x2, y2)
  8.         self.color = color
  9.         self.width = width
  10.  
  11.     def draw(self, surface):
  12.         x1, y1, x2, y2 = self.get_points()
  13.  
  14.         pygame.draw.aaline(surface, self.color, (x1, y1), (x2, y2), self.width)
  15.  
  16.     def get_points(self):
  17.         x1, y1 = self.a
  18.         x2, y2 = self.b
  19.         return x1, y1, x2, y2
  20.  
  21. class Ray:
  22.     def __init__(self, x, y, dx, dy, color, width=1):
  23.         self.pos = pygame.Vector2(x, y)
  24.         self.dir = pygame.Vector2(dx, dy)
  25.         self.color = color
  26.         self.width = width
  27.  
  28.     def draw(self, surface, distance=1):
  29.         x1, y1, x2, y2 = self.get_points(distance)
  30.  
  31.         pygame.draw.aaline(surface, self.color, (x1, y1), (x2, y2), self.width)
  32.  
  33.     def get_points(self, distance=1):
  34.         x1, y1 = self.pos
  35.         x2, y2 = self.pos + self.dir * distance
  36.         return x1, y1, x2, y2
  37.  
  38.     # @return None or Vector2 of intersect
  39.     def intersect_line(self, line):
  40.         if not isinstance(line, Line):
  41.             return
  42.  
  43.         x1, y1, x2, y2 = line.get_points()
  44.         x3, y3, x4, y4 = self.get_points()
  45.  
  46.         den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
  47.         if den == 0:
  48.             return
  49.  
  50.         t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den
  51.         u = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / den
  52.         if 0 < t < 1 and u > 0:
  53.             return pygame.Vector2(x1 + t * (x2 - x1),
  54.                            y1 + t * (y2 - y1))
  55.  
  56.     def look_at(self, x, y):
  57.         if x != 0 or y != 0:
  58.             self.dir = ((x, y) - self.pos).normalize()
  59.  
  60. class Main:
  61.     def __init__(self, caption, width, height, flags=0):
  62.         pygame.display.set_caption(caption)
  63.         self.surface = pygame.display.set_mode((width, height), flags)
  64.         self.rect = self.surface.get_rect()
  65.         self.clock = pygame.time.Clock()
  66.         self.running = False
  67.         self.delta = 0
  68.         self.fps = 60
  69.  
  70.         self.line_color = pygame.Color("snow")
  71.         self.walls = (Line(320, 100, 300, 300, self.line_color),
  72.                       Line(75, 150, 100, 250, self.line_color))
  73.  
  74.         self.ray = Ray(200, 200, 1, 0, self.line_color)
  75.         self.get_intersect()
  76.  
  77.     def get_intersect(self):
  78.         self.point = None
  79.         for wall in self.walls:
  80.             p =  self.ray.intersect_line(wall)
  81.             if p:
  82.                 self.point = p
  83.  
  84.     def draw(self):
  85.         for wall in self.walls:
  86.             wall.draw(self.surface)
  87.         self.ray.draw(self.surface, 20)
  88.  
  89.         if self.point:
  90.             pygame.draw.circle(self.surface, self.line_color, self.point, 5)
  91.  
  92.  
  93.     def mainloop(self):
  94.         self.running = True
  95.         while self.running:
  96.             for event in pygame.event.get():
  97.                 if event.type == pygame.MOUSEMOTION:
  98.                     self.ray.look_at(*event.pos)
  99.                     self.get_intersect()
  100.                 elif event.type == pygame.QUIT:
  101.                     self.running = False
  102.  
  103.             self.surface.fill(pygame.Color("black"))
  104.             self.draw()
  105.             pygame.display.flip()
  106.             self.delta = self.clock.tick(self.fps)
  107.  
  108. def main():
  109.     pygame.init()
  110.     app = Main("Ray Intersect Line", 400, 400)
  111.     app.mainloop()
  112.     pygame.quit()
  113.  
  114. main()
  115.  
Advertisement
Add Comment
Please, Sign In to add comment