import pygame
+pygame.init()
+
from particle import PointParticle
SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
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():
is_running = False
for particle in particles:
- particle.update(delta)
+ particle.update(delta, particles)
screen.fill((255, 255, 255))
for particle in particles:
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)