Created
April 25, 2017 17:57
-
-
Save threepipes/604d44e398d87314d1580cf0293830d2 to your computer and use it in GitHub Desktop.
pythonによる円と線分の交差判定テスト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| import pygame | |
| import sys | |
| import random | |
| import shapely.geometry as sg | |
| class Pos: | |
| def __init__(self, x, y): | |
| self.x = x | |
| self.y = y | |
| def __add__(self, other): | |
| return Pos(self.x + other.x, self.y + other.y) | |
| def __sub__(self, other): | |
| return Pos(self.x - other.x, self.y - other.y) | |
| def __mul__(self, other): | |
| return Pos(self.x * other.x, self.y * other.y) | |
| def norm(self): | |
| return Pos(self.y, -self.x) | |
| def pos(self): | |
| return (self.x, self.y) | |
| class Line: | |
| def __init__(self, p1, p2): | |
| self.p1 = p1 | |
| self.p2 = p2 | |
| self.color = (255, 255, 255) | |
| self.sg_line = sg.LineString([p1.pos(), p2.pos()]) | |
| def draw(self, canvas, screen): | |
| canvas.line(screen, self.color, self.p1.pos(), self.p2.pos()) | |
| class Circle: | |
| def __init__(self, center, r): | |
| self.center = center | |
| self.r = r | |
| self.color = (255, 255, 255) | |
| self.sg_circle = sg.Point(center.x, center.y).buffer(r).boundary | |
| def intersection(self, line): | |
| points = self.sg_circle.intersection(line.sg_line) | |
| if isinstance(points, sg.Point): | |
| return [points.coords[0]] | |
| return [ | |
| geom.coords[0] for geom in self.sg_circle.intersection(line.sg_line).geoms | |
| ] | |
| def draw(self, canvas, screen): | |
| canvas.circle(screen, self.color, self.center.pos(), self.r, 1) | |
| WID = 800 | |
| HEI = 800 | |
| def draw(pos_list): | |
| (w, h) = (WID, HEI) | |
| (x, y) = (w//2, h//2) | |
| pygame.init() | |
| pygame.display.set_mode((w, h), 0, 32) | |
| screen = pygame.display.get_surface() | |
| turn = 0 | |
| circle = Circle(Pos(WID // 2, HEI // 2), 100) | |
| while True: | |
| pygame.display.update() | |
| pygame.time.wait(30) | |
| screen.fill((0, 20, 0, 0)) | |
| circle.draw(pygame.draw, screen) | |
| if turn < len(pos_list): | |
| pos_list[turn].draw(pygame.draw, screen) | |
| for pos in circle.intersection(pos_list[turn]): | |
| pygame.draw.circle(screen, (0, 255, 255), (int(pos[0]), int(pos[1])), 5) | |
| pressed = pygame.key.get_pressed() | |
| if pressed[pygame.K_LEFT] and turn > 0: | |
| turn -= 1 | |
| if pressed[pygame.K_RIGHT] and turn < len(pos_list)-1: | |
| turn += 1 | |
| for event in pygame.event.get(): | |
| if is_exit(event): | |
| pygame.quit() | |
| return | |
| def is_exit(event): | |
| return ( | |
| event.type == pygame.KEYDOWN and | |
| event.key == pygame.K_ESCAPE or | |
| event.type == pygame.QUIT | |
| ) | |
| def create_pos_list(): | |
| pos_n = 100 | |
| pos_list = [] | |
| for i in range(pos_n): | |
| x1 = random.random() * 300 + 100 | |
| y1 = random.random() * 300 + 100 | |
| x2 = random.random() * 300 + 300 | |
| y2 = random.random() * 300 + 300 | |
| pos_list.append(Line(Pos(x1, y1), Pos(x2, y2))) | |
| return pos_list | |
| if __name__ == '__main__': | |
| pos_list = create_pos_list() | |
| draw(pos_list) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment