Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- #
- # http://stackoverflow.com/questions/41862541/simple-physics-string
- #
- from math import sqrt
- import pygame
- # --- constants ---
- WHITE = (255, 255, 255)
- BLACK = ( 0, 0, 0)
- FPS = 60
- # --- classes ---
- class Node():
- def __init__(self, position, mass=100, velocity=None):
- # default value for velocity,
- # list can't be used directly in `def`
- if velocity is None:
- velocity = [0, 1]
- self.position = position #[:]
- self.mass = mass
- self.velocity = velocity
- def update(self):
- self.position[0] += self.velocity[0]
- self.position[1] += self.velocity[1]
- class String():
- def __init__(self, nodes, gravity=.981, spring_constant=10, iterations=1):
- self.nodes = nodes #[:]
- self.gravity = gravity
- self.spring_constant = spring_constant
- self.iterations = iterations
- self.set_distance = 1
- def calculateForces(self):
- for x in range(self.iterations):
- for i in range(1, len(self.nodes)):
- previous = self.nodes[i-1]
- current = self.nodes[i]
- dx = current.position[0] - previous.position[0]
- dy = current.position[1] - previous.position[1]
- # maybe to use pygame.math.Vector2.distance_squared_to() ?
- # http://pygame.org/docs/ref/math.html#pygame.math.Vector2
- distance = sqrt(dx**2 + dy**2)
- force = -self.spring_constant * (distance - self.set_distance)
- force = force / current.mass
- # maybe to calculate `force/distance` only once
- nDistanceVector_x = (dx / distance) * force
- nDistanceVector_y = (dy / distance) * force
- current.velocity[0] = 0.71 * current.velocity[0] + nDistanceVector_x
- current.velocity[1] = 0.71 * current.velocity[1] + nDistanceVector_y + self.gravity
- current.update()
- # --- main ---
- # - init -
- pygame.init()
- screen = pygame.display.set_mode((500, 500))
- # - objects -
- a = [Node([250 + i * 10, 100], 140) for i in range(25)]
- s = String(a)
- # - mainloop -
- clock = pygame.time.Clock()
- while True:
- # - events -
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- pygame.quit()
- quit()
- # - updates -
- s.calculateForces()
- points = [node.position for node in a]
- # - draws -
- screen.fill(WHITE)
- pygame.draw.aalines(screen, BLACK, False, points)
- pygame.display.update()
- # - FPS -
- clock.tick(FPS)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement