Advertisement
furas

Python - Spring #1 - (StackOverflow.com)

Jan 26th, 2017
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.66 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. #
  4. # http://stackoverflow.com/questions/41862541/simple-physics-string
  5. #
  6.  
  7. from math import sqrt
  8. import pygame
  9.  
  10. # --- constants ---
  11.  
  12. WHITE = (255, 255, 255)
  13. BLACK = (  0,   0,   0)
  14.  
  15. FPS = 60
  16.  
  17. # --- classes ---
  18.  
  19. class Node():
  20.  
  21.     def __init__(self, position, mass=100, velocity=None):
  22.  
  23.         # default value for velocity,
  24.         # list can't be used directly in `def`
  25.         if velocity is None:
  26.             velocity = [0, 1]
  27.  
  28.         self.position = position #[:]
  29.         self.mass = mass
  30.         self.velocity = velocity
  31.  
  32.     def update(self):
  33.         self.position[0] += self.velocity[0]
  34.         self.position[1] += self.velocity[1]
  35.  
  36. class String():
  37.  
  38.     def __init__(self, nodes, gravity=.981, spring_constant=10, iterations=1):
  39.         self.nodes = nodes #[:]
  40.         self.gravity = gravity
  41.         self.spring_constant = spring_constant
  42.         self.iterations = iterations
  43.         self.set_distance = 1
  44.  
  45.     def calculateForces(self):
  46.         for x in range(self.iterations):
  47.             for i in range(1, len(self.nodes)):
  48.  
  49.                 previous = self.nodes[i-1]
  50.                 current = self.nodes[i]
  51.  
  52.                 dx = current.position[0] - previous.position[0]
  53.                 dy = current.position[1] - previous.position[1]
  54.  
  55.                 # maybe to use pygame.math.Vector2.distance_squared_to() ?
  56.                 # http://pygame.org/docs/ref/math.html#pygame.math.Vector2
  57.                 distance = sqrt(dx**2 + dy**2)
  58.                 force = -self.spring_constant * (distance - self.set_distance)
  59.                 force = force / current.mass
  60.  
  61.                 # maybe to calculate `force/distance` only once
  62.                 nDistanceVector_x = (dx / distance) * force
  63.                 nDistanceVector_y = (dy / distance) * force
  64.  
  65.                 current.velocity[0] = 0.71 * current.velocity[0] + nDistanceVector_x
  66.                 current.velocity[1] = 0.71 * current.velocity[1] + nDistanceVector_y + self.gravity
  67.                 current.update()
  68.  
  69. # --- main ---
  70.  
  71. # - init -
  72.  
  73. pygame.init()
  74.  
  75. screen = pygame.display.set_mode((500, 500))
  76.  
  77. # - objects -
  78.  
  79. a = [Node([250 + i * 10, 100], 140) for i in range(25)]
  80. s = String(a)
  81.  
  82. # - mainloop -
  83.  
  84. clock = pygame.time.Clock()
  85.  
  86. while True:
  87.  
  88.     # - events -
  89.  
  90.     for event in pygame.event.get():
  91.         if event.type == pygame.QUIT:
  92.             pygame.quit()
  93.             quit()
  94.  
  95.     # - updates -
  96.  
  97.     s.calculateForces()
  98.     points = [node.position for node in a]
  99.  
  100.     # - draws -
  101.  
  102.     screen.fill(WHITE)
  103.     pygame.draw.aalines(screen, BLACK, False, points)
  104.     pygame.display.update()
  105.  
  106.     # - FPS -
  107.  
  108.     clock.tick(FPS)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement