An interactive 2D physics simulation of ski jump landing geometry, built with Python and Pygame. Simulates a skier's inrun, takeoff, and flight trajectory against two analytically derived landing curves, each designed to limit the Equivalent Fall Height (EFH) to 1 m at the point of maximum impact. The landing curve geometry was calculated as part of a university course; this simulation was written to validate the results interactively. Developed as part of M.Sc. Sport Technology coursework at the University of Bayreuth.
In ski jump design, the shape of the landing slope directly determines the impact forces a jumper experiences on landing. The Equivalent Fall Height (EFH) is the standard safety metric used by the FIS, which represents the height from which a jumper would have to fall freely to experience the same normal impact force as on the actual slope. The two landing curves in this simulation were derived by computing discrete data points that satisfy EFH ≤ 1 m across the landing zone, then fitting a cubic polynomial to those points.
| Mode | Button | Speed v_0 | Landing Curve | Purpose |
|---|---|---|---|---|
| 0 | v_0=0 | L0 |
0 m/s | Calculated for 0 m/s | ✅ Correct pairing |
| 1 | v_0=2 | L2 |
2 m/s | Calculated for 2 m/s | ✅ Correct pairing |
| 2 | v_0=0 | L2! |
0 m/s | Calculated for 2 m/s | |
| 3 | v_0=2 | L0! |
2 m/s | Calculated for 0 m/s |
The landing curves are calculated based on the full takeoff velocity, which is composed of a fixed slope-parallel component of 18 m/s, representing the skier's speed along the jump, and an additional vertical takeoff component v_0. The parameter v_0 therefore refers exclusively to the vertical jumping speed at liftoff: 0 m/s for a passive skier leaving the jump without any vertical impulse, and 2 m/s for an active jump. Modes 2 and 3 use deliberately mismatched landing curves to visualize the consequence of applying a landing geometry that was not calculated for the actual v_0 condition. In this case the EFH constraint of 1 m is no longer satisfied. A jumper would either experience significantly higher impact forces than designed for, or the slope would be unnecessarily conservative.
![]() Mode 0 — v_0=0, correct pairing |
![]() Mode 1 — v_0=2, correct pairing |
![]() Mode 2 — v_0=0, mismatched curve |
![]() Mode 3 — v_0=2, mismatched curve |
.
├─ assets/
│ ├── demo.gif # demo animation for README
│ ├── screenshot_mode0.jpg
│ ├── screenshot_mode1.jpg
│ ├── screenshot_mode2.jpg
│ └── screenshot_mode3.jpg
├─ skijump_sim.py # simulation script
├─ requirements.txt # Python runtime dependencies
├─ requirements-build.txt # dependencies to build the app bundle
├─ LICENSE
└─ README.md
- Python 3.10+
- Pygame 2.0+
- PyInstaller 6.0+ (only required for building app bundles)
git clone https://github.com/dagebg/ski-jump-simulation.git
cd ski-jump-simulationpython -m venv .venv
source .venv/bin/activate # on Windows: .venv\Scripts\activatepip install -r requirements.txt # install runtime dependencies (enough for running the simulation)
# optional:
pip install -r requirements-build.txt # install dependencies for building the app bundle python skijump_sim.py # assuming 'python' points to Python 3.10+Use the Starting Height slider to set the drop height, select a simulation mode, and press Start to run the simulation. Press Restart to reset and Stop to pause mid-flight.
pyinstaller --onefile --windowed --name SkiJumpSim skijump_sim.pyThe app bundle is output to dist/SkiJumpSim.app. Launch it via Finder or from the terminal:
open dist/SkiJumpSim.apppyinstaller --onefile --windowed --name SkiJumpSim skijump_sim.pyThe executable is output to dist/SkiJumpSim.exe. Launch it via the file explorer or from the terminal:
.\dist\SkiJumpSim.exeAfter the first build, a SkiJumpSim.spec file is generated in the project root. Subsequent builds can use this file to generate the app bundle.
pyinstaller SkiJumpSim.specThe app bundle is not signed. On macOS, you may need to right-click the app bundle and select "Open" on first launch to allow it to run.
- EFH curve overlay — draw the Equivalent Fall Height live on the landing slope
- Live impact vectors — render velocity v, slope normal n, and normal component v⊥ at landing
- Trajectory trace — fading dotted flight path drawn after each jump
- CSV export — save jump parameters (start height, v_0, landing distance, EFH) to a
.csvfile - Web version via
pygbag— run the simulation directly in a browser - Load hill geometry from a JSON/CSV config file instead of hardcoded coefficients
- Resizable window
- Split into multiple files:
simulation.py,renderer.py,gui.py,constants.py,main.py
The code in this repository is licensed under the MIT License - see the LICENSE file for details.




