Verlet integrator, to deal with an argument from the pub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.5KB

  1. # Import the pygame library and initialise the game engine
  2. import pygame
  3. import numpy as np
  4. pygame.init()
  5. # Initialize Pygame
  6. size = (800, 800)
  7. CENTER = np.array(size) / 2
  8. WHITE = (255, 255, 255)
  9. DAMPING = 0.99
  10. screen = pygame.display.set_mode(size)
  11. pygame.display.set_caption("Patrick")
  12. running = True
  13. clock = pygame.time.Clock()
  14. class Ball(object):
  15. def __init__(self, x, y, radius=10, mass=1):
  16. self.pos = np.array([x, y])
  17. self.last_pos = np.array([x, y])
  18. self.velocity = np.array([0, 0])
  19. self.radius = radius
  20. self.mass = mass
  21. def render(self, screen):
  22. x, y = self.pos + CENTER
  23. pygame.draw.circle(screen, WHITE, [int(x), int(y)], self.radius, 2)
  24. def update(self):
  25. self.pos[1] += .05
  26. if self.pos[1] > 400:
  27. self.pos[1] = 400
  28. self.last_pos[1] = 400
  29. self.velocity[1] = -.5 * self.velocity[1]
  30. self.pos += self.velocity
  31. self.velocity = self.pos - self.last_pos
  32. self.velocity *= DAMPING
  33. self.last_pos = np.array(self.pos)
  34. class Spring(object):
  35. def __init__(self, a, b, length=None, k=0.3):
  36. self.a = a
  37. self.b = b
  38. self.k = k
  39. self.length = self.compute_length() if length is None else length
  40. print(self.length)
  41. def render(self, screen):
  42. x1, y1 = self.a.pos + CENTER
  43. x2, y2 = self.b.pos + CENTER
  44. pygame.draw.line(screen, WHITE, [x1, y1], [x2, y2])
  45. def compute_length(self):
  46. x1, y1 = self.a.pos + CENTER
  47. x2, y2 = self.b.pos + CENTER
  48. return np.sqrt((x2 - x1)**2 + (y2 - y1)**2)
  49. def update(self):
  50. current_length = self.compute_length()
  51. delta = self.b.pos - self.a.pos
  52. delta /= current_length
  53. stretch = (current_length - self.length) / self.length
  54. self.a.velocity += stretch * delta * self.k
  55. self.b.velocity -= stretch * delta * self.k
  56. if __name__ == '__main__':
  57. balls = [Ball(0., 0.), Ball(100., 100.)]
  58. springs = [Spring(balls[0], balls[1], length=100)]
  59. while running:
  60. for event in pygame.event.get():
  61. if event.type == pygame.QUIT:
  62. running = False
  63. screen.fill((0, 0, 0))
  64. # Update physics
  65. for ball in balls:
  66. ball.update()
  67. for spring in springs:
  68. spring.update()
  69. # Draw
  70. for ball in balls:
  71. ball.render(screen)
  72. for spring in springs:
  73. spring.render(screen)
  74. pygame.display.flip()
  75. clock.tick(60)
  76. pygame.quit()