Skip to content

77natsu77/verlet-integration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Verlet Integration Physics — Console Simulation

CI

A real-time, constraint-based rigid-body physics engine built from scratch in C# — rendered entirely in the terminal.

This project implements Verlet Integration, the same numerical method used by professional game physics engines (Havok, PhysX, Bullet), to simulate a rigid square under gravity, collision, and user-applied forces — all in a 40×20 ASCII console viewport.


Technical Depth

1. Verlet Integration (The Core Formula)

Classical physics engines store position and velocity separately. Verlet Integration eliminates explicit velocity, deriving it implicitly from positional history:

NewPosition = CurrentPosition + (CurrentPosition - OldPosition) + Acceleration × Δt²

Why this is powerful:

  • Velocity is implicit — it emerges from (X - OldX), making the simulation naturally stable
  • Energy dissipation is trivial: multiply the velocity term by < 1.0 (e.g., 0.99f) for damping
  • Constraints can be applied directly to positions without destabilising the integrator

In code (Point.Update):

float vx = (X - OldX) * 0.99f; // Implicit velocity with 1% damping
OldX = X;
X += vx + AccelX * (deltaTime * deltaTime);

2. Constraint Solving (Position-Based Dynamics)

Each Stick represents a distance constraint between two points. Every frame, sticks measure their current length vs. their rest length and push the endpoints apart or together to correct the error:

difference = (RestLength - CurrentLength) / CurrentLength
offsetX    = dx × difference × 0.5

Both endpoints are nudged by half the correction each — a symmetric, mass-equal projection.

The stability trick: This correction is run 5 times per frame (the iteration loop). More iterations = stiffer, more accurate constraints. This is the foundation of XPBD (Extended Position-Based Dynamics), the algorithm behind cloth and soft-body physics in modern AAA games.


3. Rigid Body from Particles

A rigid square is not a single object — it is 4 particles + 6 sticks:

P0 ---S0--- P1
|  \      / |
S3   S4  S5  S1
|      \/   |
P3 ---S2--- P2

The 4 outer sticks form the shell. The 2 diagonal braces (S4, S5) are critical — without them, the square collapses into a rhombus because the shell alone is geometrically underdetermined. This is the computational equivalent of structural triangulation in civil engineering.


4. Collision Response via Verlet

When a point breaches the floor boundary, the engine doesn't apply an impulse — it repositions OldY to create an outward velocity on the next frame:

float vy = Y - OldY;          // Capture downward velocity
Y = height;                    // Snap to boundary
OldY = Y + (vy * 1.25f);      // Exaggerate OldY → net upward velocity next frame

The 1.25f multiplier gives a slight bounce coefficient > 1.0 for a satisfying visual pop. Wall collisions use 0.5f for a more damped response.


5. Impulse via Position Manipulation

User keypresses deliver a "kick" by directly modifying OldX for all points:

foreach (var p in points) p.OldX -= 5.0f; // Right arrow kick

Subtracting from OldX means the integrator sees a large (X - OldX) delta next frame — equivalent to instantaneously setting a horizontal velocity of 5.0 units/frame. No force accumulation needed.


Installation & Usage

Prerequisites

  • .NET SDK (tested on .NET 6+)
  • A terminal with at least 40 columns × 20 rows

Run

git clone https://github.com/77natsu77/verlet-integration-console.git
cd verlet-integration-console
dotnet run --project VerletSim/VerletSim.csproj

Controls

Key Action
Right Arrow Kick the square to the right
Left Arrow Kick the square to the left
Ctrl+C Exit simulation

Tweak the Physics

All key parameters are at the top of Program.cs:

Parameter Location Effect
0.99f damping Point.Update() Energy loss per frame (1.0 = frictionless)
1.25f bounce Point.Constraints() Floor bounciness
AccelY = 20f Point constructor Gravitational acceleration
5 iterations Main loop Constraint solver passes (more = stiffer)
0.16f deltaTime p.Update(0.16f) Simulation timestep (~60fps)

Learning Outcomes

Building this project developed mastery of:

  • Numerical Integration — Understanding why Euler integration diverges and how Verlet's position-history approach achieves stability without storing velocity state
  • Constraint-Based Physics — Implementing iterative position projection (the core of PBD/XPBD) and understanding the trade-off between iteration count and performance
  • Rigid Body Simulation from First Principles — Discovering that rigidity is an emergent property of correctly braced particle systems, not a primitive concept
  • Collision Response without Impulses — Engineering bouncing and wall reflection purely through positional manipulation of the Verlet history
  • Console Rendering — Using Console.SetCursorPosition, line drawing via parametric interpolation (t = i / segments), and frame timing for smooth animation
  • Structural Engineering Intuition — The diagonal brace requirement mirrors real-world triangulation (why triangles are the only geometrically stable polygon)

Architecture

Program.cs
├── Main()          — Simulation loop: input → update → render
├── Point           — Particle with Verlet state (X, Y, OldX, OldY, Accel)
│   ├── Update()    — Verlet integration step
│   └── Constraints() — Boundary collision response
├── Stick           — Distance constraint between two Points
│   └── Update()    — Symmetric position projection
└── DrawStick()     — Bresenham-style line rasterisation to console

Extensions & Ideas

  • Add a hanging rope (chain of points, no diagonals needed)
  • Implement mouse interaction to drag points
  • Port to a graphics context (WinForms / MonoGame) for a 2D renderer
  • Add breakable constraints (sticks that snap beyond a stretch threshold)
  • Simulate cloth as a 2D grid of particles and sticks

Further Reading


Built as a self-directed exploration of numerical methods and game physics fundamentals.

About

A physics simulation to accompany my introduction to numerical methods (core logic is fined, but need to work on visual aspect)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages