import numpy as np
import matplotlib.pyplot as plt
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
pygame.init()
pygame.display.set_caption('Vector Animation')
window_surface = pygame.display.set_mode((800, 600))
text_font = pygame.font.SysFont('Brass Mono', 30)
if text_font is None:
text_font = pygame.font.SysFont('Monospace', 30)
background = pygame.Surface((800, 600))
background.fill(WHITE)
is_running = True
origin = pygame.Vector2(400, 300)
vector = np.array([0, -200])
transform = np.array([[0, 1], [-1, 0]])
def vec_from_array(vec):
return pygame.Vector2(vec[0], vec[1])
def draw_arrow(
surface: pygame.Surface,
start: pygame.Vector2,
end: pygame.Vector2,
color: pygame.Color,
body_width: int = 2,
head_width: int = 6,
head_height: int = 6,
):
"""Draw an arrow between start and end with the arrow head at the end.
Args:
surface (pygame.Surface): The surface to draw on
start (pygame.Vector2): Start position
end (pygame.Vector2): End position
color (pygame.Color): Color of the arrow
body_width (int, optional): Defaults to 2.
head_width (int, optional): Defaults to 4.
head_height (float, optional): Defaults to 2.
"""
arrow = start - end
angle = arrow.angle_to(pygame.Vector2(0, -1))
body_length = arrow.length() - head_height
head_verts = [
pygame.Vector2(0, head_height / 2), pygame.Vector2(head_width / 2, -head_height / 2), pygame.Vector2(-head_width / 2, -head_height / 2), ]
translation = pygame.Vector2(0, arrow.length() - (head_height / 2)).rotate(-angle)
for i in range(len(head_verts)):
head_verts[i].rotate_ip(-angle)
head_verts[i] += translation
head_verts[i] += start
pygame.draw.polygon(surface, color, head_verts)
if arrow.length() >= head_height:
body_verts = [
pygame.Vector2(-body_width / 2, body_length / 2), pygame.Vector2(body_width / 2, body_length / 2), pygame.Vector2(body_width / 2, -body_length / 2), pygame.Vector2(-body_width / 2, -body_length / 2), ]
translation = pygame.Vector2(0, body_length / 2).rotate(-angle)
for i in range(len(body_verts)):
body_verts[i].rotate_ip(-angle)
body_verts[i] += translation
body_verts[i] += start
pygame.draw.polygon(surface, color, body_verts)
clock = pygame.time.Clock()
vector_clock = 0
radius = 10
while is_running:
pygame.draw.ellipse(window_surface, BLACK, (origin[0]-(radius * 0.5), origin[1]-(radius*0.5), radius, radius))
time_delta = clock.tick(60)/1000.0
for event in pygame.event.get():
if event.type == pygame.QUIT:
is_running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
is_running = False
draw_arrow(window_surface, origin, vec_from_array(vector+origin), BLACK)
if (vector_clock == 0):
window_surface.blit(background, (0, 0))
vector = vector.dot(transform)
text_surface = text_font.render('Rotate 90°', 100, 250)
window_surface.blit(text_surface, (0, 0))
if (vector_clock >= 1.0 and vector_clock <= 1.1):
window_surface.blit(background, (0, 0))
vector_clock += time_delta
if (vector_clock >= 5.0) :
vector_clock = 0
pygame.display.update()