Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > de.alt.folklore.computer > #50746
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Newsgroups | de.alt.folklore.computer |
| Subject | Historische Programme in Python rekonstruiert |
| Date | 2025-06-14 20:04 +0000 |
| Organization | Stefan Ram |
| Message-ID | <Simulation-20250614210329@ram.dialup.fu-berlin.de> (permalink) |
Als Schüler wollte ich meinen Computer in der Schule vorführen, das
war vielleicht 1978 oder 1979. Im Physikunterricht stellte ich eine
Gas-Simulation in Maschinensprache vor, die zeigt, daß sich eine
Maxwell-Verteilung ergibt - hatte ich aber nicht selber geschrieben.
Der Chatbot hat sofort auf meinen ersten Prompt hin das ganze
Programm in Python rekonstruiert, es lief sofort. Ich mußte ihn
dann nur darum bitten, daß sich zunächst nur ein Atom bewegt
und daß die Stöße noch etwas realistischer werden.
Nun ist die Spannung groß: Wird sich eine Maxwell-Verteilung
einstellen??
# Maxgas
# -----------------------------------------------------------------------------
# Copyright 2025 Stefan
#
# Written by Stefan Ram on June 14, 2025.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -----------------------------------------------------------------------------
import tkinter as tk
import random
import math
class Ball:
def __init__(self, x, y, vx, vy, radius):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.radius = radius
def move(self, dt, width, height, balls):
# Move ball
self.x += self.vx * dt
self.y += self.vy * dt
# Wall collisions
if self.x - self.radius < 0:
self.x = self.radius
self.vx = -self.vx
elif self.x + self.radius > width:
self.x = width - self.radius
self.vx = -self.vx
if self.y - self.radius < 0:
self.y = self.radius
self.vy = -self.vy
elif self.y + self.radius > height:
self.y = height - self.radius
self.vy = -self.vy
# Ball-ball collisions (realistic elastic)
for ball in balls:
if ball is not self:
dx = self.x - ball.x
dy = self.y - ball.y
dist = math.hypot(dx, dy)
if dist < self.radius + ball.radius:
# Normalize collision vector
nx = dx / dist if dist > 0 else 1
ny = dy / dist if dist > 0 else 0
# Relative velocity
dvx = self.vx - ball.vx
dvy = self.vy - ball.vy
# Velocity along collision normal
vel_along_normal = dvx * nx + dvy * ny
# Only resolve collision if balls are moving towards each other
if vel_along_normal < 0:
# Impulse (elastic collision, same mass)
impulse = vel_along_normal
# Apply impulse to both balls
self.vx -= impulse * nx
self.vy -= impulse * ny
ball.vx += impulse * nx
ball.vy += impulse * ny
# Move balls apart to prevent sticking
overlap = (self.radius + ball.radius) - dist
self.x += overlap * nx * 0.5
self.y += overlap * ny * 0.5
ball.x -= overlap * nx * 0.5
ball.y -= overlap * ny * 0.5
class App:
def __init__(self, root):
self.root = root
self.width = 900
self.height = 600
self.plot_width = int(self.width * 0.2)
self.sim_width = self.width - self.plot_width
self.canvas = tk.Canvas(root, width=self.width, height=self.height)
self.canvas.pack()
self.balls = []
self.n_balls = 30
self.ball_radius = 5
# Create balls: all at rest except one fast ball
for i in range(self.n_balls):
x = random.uniform(self.ball_radius, self.sim_width - self.ball_radius)
y = random.uniform(self.ball_radius, self.height - self.ball_radius)
if i == 0: # Make the first ball fast
speed = 10
angle = random.uniform(0, 2 * math.pi)
vx = speed * math.cos(angle)
vy = speed * math.sin(angle)
else: # All other balls at rest
vx = 0
vy = 0
self.balls.append(Ball(x, y, vx, vy, self.ball_radius))
self.update()
def update(self):
self.canvas.delete("all")
# Draw divider
self.canvas.create_line(self.sim_width, 0, self.sim_width, self.height, fill="gray")
# Draw balls
for ball in self.balls:
ball.move(0.5, self.sim_width, self.height, self.balls)
x1, y1 = ball.x - ball.radius, ball.y - ball.radius
x2, y2 = ball.x + ball.radius, ball.y + ball.radius
self.canvas.create_oval(x1, y1, x2, y2, fill="blue")
# Compute and plot speed distribution
speeds = [math.hypot(ball.vx, ball.vy) for ball in self.balls]
max_speed = max(speeds) if speeds else 1
bin_size = max_speed / 10
bins = [0] * 10
for s in speeds:
idx = min(int(s / bin_size), 9) if bin_size > 0 else 0
bins[idx] += 1
# Draw histogram
hist_height = self.height * 0.8
max_count = max(bins) if bins else 1
for i, count in enumerate(bins):
x1 = self.sim_width + 10 + i * (self.plot_width - 30) / 10
x2 = x1 + (self.plot_width - 30) / 10 - 2
bar_height = hist_height * count / max_count
y1 = self.height - 20 - bar_height
y2 = self.height - 20
self.canvas.create_rectangle(x1, y1, x2, y2, fill="red")
self.root.after(20, self.update)
root = tk.Tk()
app = App(root)
root.mainloop()
Back to de.alt.folklore.computer | Previous | Next — Next in thread | Find similar
Historische Programme in Python rekonstruiert ram@zedat.fu-berlin.de (Stefan Ram) - 2025-06-14 20:04 +0000
Re: Historische Programme in Python rekonstruiert Sebastian Barthel <naitsabes@freenet.de> - 2025-06-15 12:59 +0000
Re: Historische Programme in Python rekonstruiert ram@zedat.fu-berlin.de (Stefan Ram) - 2025-06-15 13:18 +0000
Re: Historische Programme in Python rekonstruiert "F. W." <me@home.invalid> - 2025-06-16 08:10 +0200
Re: Historische Programme in Python rekonstruiert Gerrit Heitsch <gerrit@laosinh.s.bawue.de> - 2025-06-16 08:52 +0200
Re: Historische Programme in Python rekonstruiert "F. W." <me@home.invalid> - 2025-06-16 09:49 +0200
Re: Historische Programme in Python rekonstruiert Gerrit Heitsch <gerrit@laosinh.s.bawue.de> - 2025-06-16 09:54 +0200
Re: Historische Programme in Python rekonstruiert "F. W." <me@home.invalid> - 2025-06-16 11:38 +0200
csiph-web