Einführung

In diesem Beitrag soll gezeigt werden, wie mit einem Python Programm die Flugbahn eines Geschosses berechnet werden kann. Als Eingabe wird folgendes eingegeben: Mündungsgeschwindigkeit, Geschossgewicht, Ballistischer Koeffizient, Zielfernrohrhöhe
Als Ausgabe wird eine Tabelle mit Geschwindigkeit, Energie, Geschossabfall (0–300 m in 50 m-Schritten) unter Berücksichtigung des Luftwiderstands (G1-Modell) berechnet.
Zur besseren Visualisierung der Ergebnisse wird eine grafische Darstellung der Flugbahn relativ zur Visierlinie erstellt.

Das Programm simuliert die ballistische Flugbahn eines Geschosses, indem es die wichtigsten physikalischen Größen berechnet:

Diese Werte definieren die Eigenschaften der Patrone und die Ausgangsbedingungen.


		v0 = 1050              # Mündungsgeschwindigkeit in m/s
		mass = 0.0032          # Geschossmasse in kg
		bc = 0.200             # Ballistischer Koeffizient (G1)
		scope_height = 0.045   # Zielfernrohrhöhe in m
	

Hier wird die Geschwindigkeit über die Entfernung berechnet – exponentieller Abfall durch Luftwiderstand. Je höher der BC, desto weniger bremst die Luft das Geschoss.


		def velocity_at_distance(v0, bc, distance):
		k = air_density / (bc * 1000)
		return v0 * np.exp(-k * distance)
	

Berechnung der Energie erfolgt über folgenden Code-Abschnitt: Berechnung der Energie erfolgt überdie klassische Formel der Kinetik. Die Flugzeit ergibt sich aus der Entfernung geteilt durch Geschwindigkeit. Und der Abfall also wie weit das Geschoss durch Gravitation sinkt – relativ zur Visierlinie (Zielfernrohrhöhe wird berücksichtigt)


		E = 0.5 * mass * v**2
		t = d / v
		drop = -0.5 * g * t**2 + scope_height
	

Die berechneten Ergebnisse werden dann als Tabelle und in Form einer Flugbahn dargestellt:


		results.append((d, round(v, 2), round(E, 2), round(drop * 100, 2)))

		plt.plot(x_vals, y_vals, marker='o')

	

Alles zusammen sieht dann so aus:


		import numpy as np
		import matplotlib.pyplot as plt

		# Eingabewerte
		v0 = 1050              # Mündungsgeschwindigkeit in m/s
		mass = 0.0032          # Geschossmasse in kg
		bc = 0.200             # Ballistischer Koeffizient (G1)
		scope_height = 0.045   # Zielfernrohrhöhe in m (4.5 cm)
		air_density = 1.225    # kg/m³ (Standard)
		g = 9.81               # Erdbeschleunigung

		# Entfernungsschritte
		distances = np.arange(0, 301, 50)  # 0 bis 300 m in 50 m-Schritten

		# Funktion zur Berechnung der Geschwindigkeit mit Luftwiderstand (vereinfachtes Modell)
		def velocity_at_distance(v0, bc, distance):
			# Näherung: Geschwindigkeit sinkt exponentiell mit Entfernung
			# Formel: v = v0 * exp(-k * x), wobei k = Luftwiderstandskoeffizient
			k = air_density / (bc * 1000)  # Näherungswert
			return v0 * np.exp(-k * distance)

		# Berechnungen
		results = []
		for d in distances:
			v = velocity_at_distance(v0, bc, d)
			E = 0.5 * mass * v**2
			t = d / v if v > 0 else 0
			drop = -0.5 * g * t**2 + scope_height  # Relativ zur Visierlinie
			results.append((d, round(v, 2), round(E, 2), round(drop * 100, 2)))  # Drop in cm

		# Tabelle ausgeben
		print(f"{'Entfernung (m)':>15} | {'v (m/s)':>10} | {'Energie (J)':>12} | {'Abfall (cm)':>13}")
		print("-" * 60)
		for r in results:
			print(f"{r[0]:>15} | {r[1]:>10} | {r[2]:>12} | {r[3]:>13}")

		# Grafische Darstellung
		x_vals = [r[0] for r in results]
		y_vals = [r[3] for r in results]

		plt.figure(figsize=(10, 5))
		plt.plot(x_vals, y_vals, marker='o', label="Geschossabfall zur Visierlinie")
		plt.axhline(0, color='gray', linestyle='--', label="Visierlinie")
		plt.xlabel("Entfernung (m)")
		plt.ylabel("Abfall (cm)")
		plt.title("Ballistische Flugbahn – 5,6x50 R MAG (inkl. Luftwiderstand)")
		plt.legend()
		plt.grid(True)
		plt.tight_layout()
		plt.show()
	
Flugbahn
Entfernung (m) Geschwindigkeit (m/s) Energie (J) Geschossabfall (cm) Laborierung
01015.001648.800.003.2 g / 1015 m/s / BC 0.200
50982.621545.61-0.813.2 g / 1015 m/s / BC 0.200
100951.411447.18-2.853.2 g / 1015 m/s / BC 0.200
150921.321353.22-6.213.2 g / 1015 m/s / BC 0.200
200892.311263.45-10.963.2 g / 1015 m/s / BC 0.200
250864.341177.61-17.173.2 g / 1015 m/s / BC 0.200
300837.381095.45-24.893.2 g / 1015 m/s / BC 0.200
0900.001658.250.004.1 g / 900 m/s / BC 0.240
50875.841572.65-0.834.1 g / 900 m/s / BC 0.240
100852.531490.49-2.944.1 g / 900 m/s / BC 0.240
150830.031411.61-6.394.1 g / 900 m/s / BC 0.240
200808.311335.88-11.244.1 g / 900 m/s / BC 0.240
250787.331263.15-17.544.1 g / 900 m/s / BC 0.240
300767.061193.30-25.354.1 g / 900 m/s / BC 0.240

Eine etwas flexibler Programm-Version

Das nachfolgende Python Programm erlaugt es verschiedene Laborierungen (Geschoss-Arten und Gewichte) miteinander zu vergleichen. Die zu vergleichewnden Patronen müssen in der Liste "Laborierungen" spezifiziert werden.


   import numpy as np
   import plotly.graph_objects as go

   # Parameter für beide Laborierungen
   laborierungen = [
	   {"name": "3.2 g / 1015 m/s / BC 0.200", "v0": 1015, "mass": 0.0032, "bc": 0.200},
	   {"name": "4.1 g / 900 m/s / BC 0.240", "v0": 900, "mass": 0.0041, "bc": 0.240}
   ]

   scope_height = 0.045  # Zielfernrohrhöhe in m
   g = 9.81              # Erdbeschleunigung
   air_density = 1.225   # kg/m³
   distances = np.arange(0, 301, 50)  # 0–300 m in 50 m-Schritten

   # Funktion zur Berechnung der Geschwindigkeit mit Luftwiderstand
   def velocity(v0, bc, x):
	   k = air_density / (bc * 1000)
	   return v0 * np.exp(-k * x)

   # Plot vorbereiten
   fig = go.Figure()

   # Berechnung und Visualisierung für jede Laborierung
   for lab in laborierungen:
	   v_list, E_list, drop_list = [], [], []
	   for d in distances:
		   v = velocity(lab["v0"], lab["bc"], d)
		   E = 0.5 * lab["mass"] * v**2
		   t = d / v if v > 0 else 0
		   drop = -0.5 * g * t**2 + scope_height
		   v_list.append(round(v, 2))
		   E_list.append(round(E, 2))
		   drop_list.append(round(drop * 100, 2))  # in cm

	   # Flugbahn hinzufügen
	   fig.add_trace(go.Scatter(
		   x=distances,
		   y=drop_list,
		   mode='lines+markers',
		   name=f"Flugbahn – {lab['name']}",
		   hovertemplate=
			   "Entfernung: %{x} m
" + "Abfall: %{y} cm
" + f"Laborierung: {lab['name']}" )) # Layout fig.update_layout( title="Ballistische Flugbahn – 5,6x50 R MAG (inkl. Luftwiderstand)", xaxis_title="Entfernung (m)", yaxis_title="Geschossabfall zur Visierlinie (cm)", template="plotly_white", legend_title="Laborierungen", hovermode="x unified" ) fig.show()

Das Ergebnis wird graphisch dargestellt u nd zeigt die unterschiedlichen Flugbahnen:

Flugbahn Vergleich
⬅ Zurück zur Hauptseite