From a48b751ba6e46f955f1298dc280d146224d18d99 Mon Sep 17 00:00:00 2001 From: Skullheadx <94652084+Skullheadx@users.noreply.github.com> Date: Thu, 23 Nov 2023 19:03:59 -0500 Subject: [PATCH] basic prototype --- main.py | 7 ++++-- particle.py | 72 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/main.py b/main.py index 2bc367d..fc0d85b 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,7 @@ import pygame +pygame.init() + from particle import PointParticle SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600 @@ -10,7 +12,8 @@ is_running = True clock = pygame.Clock() delta = 0 -particles = [PointParticle((SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))] +particles = [PointParticle((SCREEN_WIDTH / 3, SCREEN_HEIGHT / 2)), + PointParticle((SCREEN_WIDTH * 2 / 3, SCREEN_HEIGHT / 2), -1.6e-19)] while is_running: for event in pygame.event.get(): @@ -18,7 +21,7 @@ while is_running: is_running = False for particle in particles: - particle.update(delta) + particle.update(delta, particles) screen.fill((255, 255, 255)) for particle in particles: diff --git a/particle.py b/particle.py index f4dfa35..0f2209b 100644 --- a/particle.py +++ b/particle.py @@ -1,26 +1,74 @@ import pygame +import math class PointParticle: + font = pygame.font.SysFont("arial", 75) + signs = {'+': font.render("+", True, (0, 0, 0)), + '−': font.render('−', True, (0, 0, 0))} + + BLUE = (0, 153, 255) + RED = (255, 43, 0) + + line_step = pygame.Vector2(10, 0) def __init__(self, position, charge=1.6e-19): self.position = pygame.Vector2(position) self.mouse_offset = pygame.Vector2(0, 0) self.charge = charge - self.radius = 50 + self.radius = 25 self.dragging = False - self.colour = (255, 0, 0) if self.charge < 0 else (0, 0, 255) - - def update(self, delta): - if pygame.mouse.get_pressed(3)[0]: - if not self.dragging and self.position.distance_to(pygame.mouse.get_pos()) < self.radius: - self.mouse_offset = pygame.Vector2(pygame.mouse.get_pos()) - self.position - self.dragging = True - if self.dragging: - self.position = pygame.Vector2(pygame.mouse.get_pos()) - self.mouse_offset - elif self.dragging: - self.dragging = False + self.colour = self.RED if self.charge < 0 else self.BLUE + self.sign = self.signs['−' if self.charge < 0 else '+'] + + self.num_field_lines = int(self.charge / 1.6e-19 * 8) # default will be 8 lines + self.field_line_angles = list(range(0, 360, int(360 / self.num_field_lines))) # List of angles + self.field_lines = [[] for _ in range(self.num_field_lines)] + + def update(self, delta, particles): + if self.dragging or not (True in [p.dragging for p in particles]): + if pygame.mouse.get_pressed(3)[0]: + if not self.dragging and self.position.distance_to(pygame.mouse.get_pos()) < self.radius: + self.mouse_offset = pygame.Vector2(pygame.mouse.get_pos()) - self.position + self.dragging = True + if self.dragging: + self.position = pygame.Vector2(pygame.mouse.get_pos()) - self.mouse_offset + elif self.dragging: + self.dragging = False + + particle_positions = {tuple(p.position) for p in particles} + + for field_line_index, angle in enumerate(self.field_line_angles): + self.field_lines[field_line_index].clear() + position = self.position.copy() + direction = angle + end = False + for i in range(250): + position += self.line_step.copy().rotate(math.degrees(direction)) + + electric_field_x_net = 0 + electric_field_y_net = 0 + for particle in particles: + diff = position - particle.position + if diff.length() < particle.radius and particle is not self: + end = True + break + angle = math.atan2(diff.y, diff.x) # radians + electric_field = 8.99e9 * particle.charge / pow(diff.length(), 2) + electric_field_x_net += electric_field * math.cos(angle) + electric_field_y_net += electric_field * math.sin(angle) + + direction = math.atan2(electric_field_y_net, electric_field_x_net) + self.field_lines[field_line_index].append(position.copy()) + + if end == True: + break def draw(self, surf): pygame.draw.circle(surf, self.colour, self.position, self.radius) pygame.draw.circle(surf, (0, 0, 0), self.position, self.radius, 3) + surf.blit(self.sign, self.sign.get_rect(center=self.position)) + + + for line in self.field_lines: + pygame.draw.lines(surf, (0, 255, 0), False, line, 5) -- 2.54.0