Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws2223:projekt_temperaturveraenderung [2023/08/10 14:41] max.liebscher |
ws2223:projekt_temperaturveraenderung [2023/08/12 01:40] (aktuell) JasperMittag |
||
---|---|---|---|
Zeile 53: | Zeile 53: | ||
==== Code ==== | ==== Code ==== | ||
+ | <code> | ||
+ | |||
+ | import random | ||
+ | import numpy as np | ||
+ | import pygame | ||
+ | import matplotlib.pyplot as plt | ||
+ | import collections | ||
+ | |||
+ | pygame.init() | ||
+ | |||
+ | # Fenster festlegen | ||
+ | WIDTH, HEIGHT = 700, 400 | ||
+ | WIN = pygame.display.set_mode((WIDTH, HEIGHT)) | ||
+ | pygame.display.set_caption("Brownsche Bewegung") | ||
+ | |||
+ | # Farbwerte | ||
+ | RED = (255, 82, 32) | ||
+ | BLACK = (0, 0, 0) | ||
+ | BLUE = (23, 2, 255) | ||
+ | WHITE = (255, 255, 255) | ||
+ | GREEN = (50, 205, 50) | ||
+ | YELLOW = (255, 255, 0) | ||
+ | |||
+ | FPS = 60 | ||
+ | |||
+ | # Werte für Teilchen | ||
+ | ballAmount = 100 | ||
+ | ballRadius = 3 | ||
+ | ballColor = BLUE | ||
+ | ballMasse = 10 | ||
+ | SPEED = 2 | ||
+ | |||
+ | BROWNSCHES_TEILCHEN_COLOR = RED | ||
+ | BROWNSCHES_TEILCHEN_RADIUS = 10 | ||
+ | BROSCNHES_TEILCHEN_MASSE = 50 | ||
+ | |||
+ | |||
+ | class Teilchen: | ||
+ | def __init__(self, color, radius, masse): | ||
+ | self.color = color | ||
+ | self.radius = radius | ||
+ | # zufällige Postion zuordnen | ||
+ | self.x = random.randint(radius, WIDTH - radius) | ||
+ | self.y = random.randint(radius, HEIGHT - radius) | ||
+ | self.xy = np.array([self.x, self.y]) | ||
+ | # zufälliger normierter Geschwindigkeitsvektor | ||
+ | self.vxy = np.array([random.uniform(-1, 1), random.uniform(-1, 1)]) | ||
+ | norm = np.sqrt(self.vxy[0]**2 + self.vxy[1]**2) | ||
+ | self.vxy = self.vxy / norm | ||
+ | self.masse = masse | ||
+ | # Zeitschritt | ||
+ | self.speed = SPEED | ||
+ | | ||
+ | def draw(self, win): | ||
+ | '''zeichnet das Teilchen ins Fenster''' | ||
+ | pygame.draw.circle(win, self.color, (self.x, self.y), self.radius) | ||
+ | | ||
+ | def move(self): | ||
+ | """neue Koordinaten werden berechnet durch Multiplikation vom | ||
+ | Geschwindigkeitsvektor und dem Zeitschritt""" | ||
+ | self.x += self.vxy[0] * self.speed | ||
+ | self.y += self.vxy[1] * self.speed | ||
+ | |||
+ | def borderCollision(self, stepcount): | ||
+ | """"Kollision mit einer Wand""" | ||
+ | if self.x >= WIDTH - self.radius: | ||
+ | self.x = WIDTH - self.radius | ||
+ | self.vxy[0] *= -1 | ||
+ | elif self.x <= self.radius: | ||
+ | self.x = self.radius | ||
+ | self.vxy[0] *= -1 | ||
+ | if self.y >= HEIGHT - self.radius: | ||
+ | self.y = HEIGHT - self.radius | ||
+ | self.vxy[1] *= -1 | ||
+ | elif self.y <= self.radius: | ||
+ | self.y = self.radius | ||
+ | self.vxy[1] *= -1 | ||
+ | | ||
+ | if stepcount <= 500: | ||
+ | """wenn das Teilchen weniger als 400 Schritte gemacht hat und | ||
+ | an die obere border stößt, wird der Geschwindigkeitsvektor | ||
+ | um einen bestimmten Betrag erhöht""" | ||
+ | v_add = 1 | ||
+ | betrag = np.sqrt(self.vxy[0]**2 + self.vxy[1]**2) | ||
+ | betrag_neu = betrag + v_add | ||
+ | verhaeltnis = self.vxy[0] / self.vxy[1] | ||
+ | if self.vxy[0] > 0: | ||
+ | self.vxy[0] = np.sqrt(((verhaeltnis**2) * (betrag_neu**2)) / (verhaeltnis**2 +1)) | ||
+ | self.vxy[1] = self.vxy[0] / verhaeltnis | ||
+ | elif self.vxy[0] < 0: | ||
+ | self.vxy[0] = -np.sqrt(((verhaeltnis**2) * (betrag_neu**2)) / (verhaeltnis**2 +1)) | ||
+ | self.vxy[1] = self.vxy[0] / verhaeltnis | ||
+ | else: | ||
+ | self.vxy[1] += v_add | ||
+ | | ||
+ | def ballCollision(self, ball2): | ||
+ | # Zwischenspeichern der Koordinaten | ||
+ | x_b1 = self.x | ||
+ | y_b1 = self.y | ||
+ | x_b2 = ball2.x | ||
+ | y_b2 = ball2.y | ||
+ | | ||
+ | sv_x = ball2.x - self.x | ||
+ | sv_y = ball2.y - self.y | ||
+ | distance = np.sqrt(sv_x**2 + sv_y**2) | ||
+ | | ||
+ | if distance <= self.radius + ball2.radius: | ||
+ | vxy_b1 = self.vxy | ||
+ | vxy_b2 = ball2.vxy | ||
+ | | ||
+ | # zurücksetzen der Koordinaten auf die im Zwischenspeicher | ||
+ | self.x = x_b1 | ||
+ | self.y = y_b1 | ||
+ | ball2.x = x_b2 | ||
+ | ball2.y = y_b2 | ||
+ | | ||
+ | """Berechnen der neuen Geschwindigkeitsvektoren durch Formel für den elastischen Stoß""" | ||
+ | self.vxy = (self.masse * vxy_b1 + ball2.masse * | ||
+ | (2 * vxy_b2 - vxy_b1)) / (self.masse + ball2.masse) | ||
+ | ball2.vxy = (ball2.masse * vxy_b2 + self.masse * | ||
+ | (2 * vxy_b1 - vxy_b2)) / (self.masse + ball2.masse) | ||
+ | | ||
+ | |||
+ | | ||
+ | def draw(win, balls): | ||
+ | win.fill(BLACK) | ||
+ | for ball in balls: | ||
+ | ball.draw(win) | ||
+ | pygame.display.update() | ||
+ | | ||
+ | | ||
+ | |||
+ | def main(): | ||
+ | run = 1 | ||
+ | | ||
+ | # Teilchenobjekte in eine Liste schreiben | ||
+ | balls = [] | ||
+ | for i in range(ballAmount): | ||
+ | ball = "ball"+str(i) | ||
+ | ball = Teilchen(ballColor, ballRadius, ballMasse) | ||
+ | balls.append(ball) | ||
+ | | ||
+ | brownschesTeilchen = Teilchen(BROWNSCHES_TEILCHEN_COLOR, BROWNSCHES_TEILCHEN_RADIUS, | ||
+ | BROSCNHES_TEILCHEN_MASSE) | ||
+ | balls.append(brownschesTeilchen) | ||
+ | | ||
+ | global stepcount | ||
+ | stepcount = 0 | ||
+ | | ||
+ | | ||
+ | while run: | ||
+ | draw(WIN, balls) | ||
+ | pygame.time.Clock().tick(FPS) | ||
+ | | ||
+ | for event in pygame.event.get(): | ||
+ | if event.type == pygame.QUIT: | ||
+ | run = 0 | ||
+ | break | ||
+ | | ||
+ | for ball in balls: | ||
+ | ball.borderCollision(stepcount) | ||
+ | for i in range(balls.index(ball) + 1, len(balls)): | ||
+ | ball.ballCollision(balls[i]) | ||
+ | ball.move() | ||
+ | # zählt jeden Schritt, den ein einzelnes Teilchen macht | ||
+ | stepcount += 1 | ||
+ | | ||
+ | # erstellt Liste aus allen Geschwindigkeiten und gibt sie aus wenn das Programm geschlossen wird | ||
+ | vballs_list = [] | ||
+ | for ball in balls: | ||
+ | vnorm = np.sqrt(ball.vxy[0]**2 + ball.vxy[1]**2) | ||
+ | vballs_list.append(round(vnorm)) | ||
+ | | ||
+ | | ||
+ | print(vballs_list) | ||
+ | | ||
+ | # erstellt dictionary, das Anzahl der Geschwindigkeiten zählt | ||
+ | vcounter = collections.Counter(vballs_list) | ||
+ | print(vcounter) | ||
+ | | ||
+ | # Schlüssel mit dem maximalen Wert aus dem dictionary vcounter | ||
+ | häufigkeiten = vcounter.items() | ||
+ | häufigkeiten = sorted(häufigkeiten) | ||
+ | x, y = zip(*häufigkeiten) | ||
+ | | ||
+ | plt.plot(x, y) | ||
+ | plt.show() | ||
+ | | ||
+ | pygame.quit() | ||
+ | |||
+ | |||
+ | if __name__ == '__main__': | ||
+ | main() | ||
+ | |||
+ | </code> | ||
+ | |||
+ | {{:ws2223:brown_pygame5.py.zip|}} | ||
=== Protokolle === | === Protokolle === |