Modellieren von Kräften ( Wind Gravitation)
Verfasst: Sonntag 20. Januar 2019, 17:37
Hallo liebe Forummitglieder,
ich versuche z.Z. gerade Programmbeispiele aus dem Buch Nature of Code von D. Shiffman auf Pygame und Python zu übertragen. (Kapitel 2)
Moverobjekte fallen durch Gravitation zu Boden und werden dabei durch Windkraft abgetrieben, sie prellen vom Boden ab und kommen dann zur Ruhe.
Shiffman verwendet Vektoren (PVector) für location ,velocity, usw., sowie für Kräfte, also habe ich pygame's Vector2 verwendet.
Die Methode apply_force in meinem Programm arbeitet auf einer Kopie des Kraftvektors, daher benötigte ich eine Hilfsmethode get_force, die eine
Kopie des Vektors zurückgibt.
Frage: kann ich das so machen, da ich in der Doku zu Vector2 keine copy-Methode gefunden habe
Noch eine Frage: Das Programm funktioniert , allerdings sollte es nicht ganz so funktionieren. Da keine Dämpfung auf die Objekte implementiert ist, sollten sie
unendlich lange weiter prellen, was sie aber nicht tun., denn sie kommen zur Ruhe. Was läuft hier grundsätzlich falsch.
Für Hilfe und Tipps wäre ich dankbar.
import pygame
import math
from random import randint, uniform
from copy import deepcopy
vec = pygame.math.Vector2
WIDTH = 1000
HEIGHT = 800
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
DARKGRAY = (40, 40, 40)
BG_COLOR = YELLOW
class Mover():
def __init__(self, position, size, m):
self.location = vec(0, 0)
self.location.x, self.location.y = position
self.velocity = vec(0,0)
self.acceleration = vec(0,0)
self.colour = BLUE
self.size = size
self.mass = m
self.thickness = 2
def get_force(self,force):
self.force = deepcopy(force)
return self.force
def apply_force(self,force):
f = self.get_force(force)
# 2.Newton Gesetz: Beschleunigung = Kraft / Masse
f /= self.mass
self.acceleration += f
def display(self):
pygame.draw.circle(screen, self.colour, (int(self.location.x),
int(self.location.y)), int(self.size)* int(self.mass), int(self.thickness))
def update(self):
self.velocity += self.acceleration
self.location += self.velocity
self.acceleration * 0.0 # resette nach jedem update
def check_edges(self):
#das passiert, wenn Ball Fenstergrenzen erreicht
if self.location.x > WIDTH-self.size:
self.location.x = WIDTH-self.size
self.velocity.x *= -0.8 # Dämpfung
elif self.location.x < self.size:
self.velocity.x *= -1
self.location.x = self.size
if self.location.y > HEIGHT:
self.velocity.y *= -1 # keine Dämpfung
self.location.y = HEIGHT
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(BG_COLOR)
clock = pygame.time.Clock()
# erzeuge zwei Moverobjekte
num_mover = 2
movers = []
for i in range(num_mover):
size = uniform(10, 30)
position = (uniform(size, WIDTH - size), size)
mass = uniform(1, 5)
mover = Mover(position,size, mass)
movers.append(mover)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(BG_COLOR)
for mover in movers:
# Windkraft
wind = vec(0.001, 0)
# Gravitation, direkt mit Masse skaliert -> real gravity
m = mover.mass
gravity = vec(0, 0.004*m)
mover.apply_force(wind)
mover.apply_force(gravity)
mover.update()
mover.display()
mover.check_edges()
pygame.display.set_caption('Two Movers real gravity and wind')
pygame.display.flip()
ich versuche z.Z. gerade Programmbeispiele aus dem Buch Nature of Code von D. Shiffman auf Pygame und Python zu übertragen. (Kapitel 2)
Moverobjekte fallen durch Gravitation zu Boden und werden dabei durch Windkraft abgetrieben, sie prellen vom Boden ab und kommen dann zur Ruhe.
Shiffman verwendet Vektoren (PVector) für location ,velocity, usw., sowie für Kräfte, also habe ich pygame's Vector2 verwendet.
Die Methode apply_force in meinem Programm arbeitet auf einer Kopie des Kraftvektors, daher benötigte ich eine Hilfsmethode get_force, die eine
Kopie des Vektors zurückgibt.
Frage: kann ich das so machen, da ich in der Doku zu Vector2 keine copy-Methode gefunden habe
Noch eine Frage: Das Programm funktioniert , allerdings sollte es nicht ganz so funktionieren. Da keine Dämpfung auf die Objekte implementiert ist, sollten sie
unendlich lange weiter prellen, was sie aber nicht tun., denn sie kommen zur Ruhe. Was läuft hier grundsätzlich falsch.
Für Hilfe und Tipps wäre ich dankbar.
import pygame
import math
from random import randint, uniform
from copy import deepcopy
vec = pygame.math.Vector2
WIDTH = 1000
HEIGHT = 800
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
DARKGRAY = (40, 40, 40)
BG_COLOR = YELLOW
class Mover():
def __init__(self, position, size, m):
self.location = vec(0, 0)
self.location.x, self.location.y = position
self.velocity = vec(0,0)
self.acceleration = vec(0,0)
self.colour = BLUE
self.size = size
self.mass = m
self.thickness = 2
def get_force(self,force):
self.force = deepcopy(force)
return self.force
def apply_force(self,force):
f = self.get_force(force)
# 2.Newton Gesetz: Beschleunigung = Kraft / Masse
f /= self.mass
self.acceleration += f
def display(self):
pygame.draw.circle(screen, self.colour, (int(self.location.x),
int(self.location.y)), int(self.size)* int(self.mass), int(self.thickness))
def update(self):
self.velocity += self.acceleration
self.location += self.velocity
self.acceleration * 0.0 # resette nach jedem update
def check_edges(self):
#das passiert, wenn Ball Fenstergrenzen erreicht
if self.location.x > WIDTH-self.size:
self.location.x = WIDTH-self.size
self.velocity.x *= -0.8 # Dämpfung
elif self.location.x < self.size:
self.velocity.x *= -1
self.location.x = self.size
if self.location.y > HEIGHT:
self.velocity.y *= -1 # keine Dämpfung
self.location.y = HEIGHT
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(BG_COLOR)
clock = pygame.time.Clock()
# erzeuge zwei Moverobjekte
num_mover = 2
movers = []
for i in range(num_mover):
size = uniform(10, 30)
position = (uniform(size, WIDTH - size), size)
mass = uniform(1, 5)
mover = Mover(position,size, mass)
movers.append(mover)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(BG_COLOR)
for mover in movers:
# Windkraft
wind = vec(0.001, 0)
# Gravitation, direkt mit Masse skaliert -> real gravity
m = mover.mass
gravity = vec(0, 0.004*m)
mover.apply_force(wind)
mover.apply_force(gravity)
mover.update()
mover.display()
mover.check_edges()
pygame.display.set_caption('Two Movers real gravity and wind')
pygame.display.flip()