007 - Physics System

The Physics System provides Verlet-based physics simulation.

Why Physics in Creative Coding?

Physics makes generative art come alive. A particle that follows gravity appears more natural than one that flies linearly. A swarm whose individuals react to each other creates emergent patterns that you couldn't have programmed.

Why Verlet?

There are many physics approaches. I use Verlet Integration because it is:

  • Stable – Nothing explodes even with large time steps
  • Simple – Position + previous position = velocity (implicit)
  • Constraint-friendly – "These two points should have distance X" → simply correct positions

Classic Euler integration (position += velocity * dt) accumulates errors and requires small time steps. Verlet (position_new = 2*position - position_old + acceleration*dt²) is more stable and allows larger time steps.

Why Two Levels?

The system has two separate physics worlds:

  1. PhysicsWorld – For particles, swarms, chains. Each point is a Particle.
  2. SoftShape – For deformable shapes. The vertices have their own mini-physics.

Why separate? Because a soft circle retains its internal jelly physics even when it flies around as a whole in the PhysicsWorld. The ShapePhysicsAdapter connects both worlds.

Two-Level Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                       Level 1: PhysicsWorld                             │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │                        PhysicsWorld                               │  │
│  └───────────────────────────────────────────────────────────────────┘  │
│         │              │              │              │                  │
│         ▼              ▼              ▼              ▼                  │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐            │
│  │ Particles  │ │ Behaviors  │ │Constraints │ │  Springs   │            │
│  └────────────┘ └────────────┘ └────────────┘ └────────────┘            │
└─────────────────────────────────────────────────────────────────────────┘
                                    ▲
┌───────────────────────────────────┼─────────────────────────────────────┐
│                       Adapter     │                                     │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │                    ShapePhysicsAdapter                            │  │
│  └───────────────────────────────────────────────────────────────────┘  │
└───────────────────────────────────┼─────────────────────────────────────┘
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        Level 2: SoftShape                               │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │                          SoftShape                                │  │
│  └───────────────────────────────────────────────────────────────────┘  │
│                │                              │                         │
│                ▼                              ▼                         │
│      ┌─────────────────┐          ┌────────────────────────┐            │
│      │    Vertices     │          │  Internal Constraints  │            │
│      └─────────────────┘          └────────────────────────┘            │
└─────────────────────────────────────────────────────────────────────────┘

Level 1: PhysicsWorld

  • Global point-based simulation
  • Particles with Position, Velocity, Mass
  • For: Particle systems, swarms, chains

Level 2: SoftShape

  • Shape-internal simulation
  • For: Deformable shapes (Blob, SoftCircle)

Components

Class File Function
PhysicsWorld PhysicsWorld.ts Container for Simulation
Particle Particle.ts Verlet Particle
Behavior Behavior.ts Force Interface
Constraint Constraint.ts Rule Interface
Spring Spring.ts Spring Connection
ParticleString ParticleString.ts Particle Chain
CollisionZone CollisionZone.ts Collision Zones
ProximityConnection ProximityConnection.ts Proximity-based Lines

PhysicsWorld

Container and update loop.

Update Order:

  1. Apply behaviors (forces)
  2. Update particles (Verlet)
  3. Update springs
  4. Apply constraints

API:

Method Description
addParticle(p) Add Particle
addBehavior(b) Add Behavior
addConstraint(c) Add Constraint
addSpring(s) Add Spring
update(dt) Update Simulation
clear() Remove Everything

Particle

Verlet particle.

Properties:

Property Type Description
position Vector Current Position
previousPosition Vector Previous Position
mass number Mass
locked boolean Fixed?
damping number Damping (0-1)
radius number For Collisions

Methods:

Method Description
addForce(f) Add Force
update(dt) Verlet Integration
velocity Getter/Setter for Velocity

Behaviors

Forces that act on particles.

GravityBehavior

Option Type Default Description
strength number 9.81 Strength
direction Vector (0, 1) Direction

FrictionBehavior

Option Type Default Description
coefficient number 0.02 Friction Coefficient

AttractionBehavior

Option Type Default Description
target Vector - Attraction Point
strength number 0.1 Strength
radius number 200 Effective Radius

ConstantForceBehavior

Option Type Description
force Vector Constant Force

Presets: createWindBehavior(), createUpdraftBehavior()

Flocking Behaviors (Boids)

Behavior Description
SeparationBehavior Keep Distance
AlignmentBehavior Same Direction
CohesionBehavior Stay Together
FlockingBehavior Combines All Three

Flocking Presets:

Preset Description
birds Bird Flock
fish Fish School
insects Insect Swarm
tight Tight Cohesion
loose Loose Cohesion

Constraints

Rules that particles must follow.

RectConstraint

Keeps particles in a rectangle.

Option Type Description
bounds {x,y,w,h} Rectangle
mode RectConstraintMode 'contain' or 'repel'
bounce number Bounciness (0-1)

CircularConstraint

Keeps particles in/outside a circle.

Option Type Description
center Vector Center Point
radius number Radius
mode CircularConstraintMode 'contain' or 'exclude'

DistanceConstraint

Fixed distance between two particles.

Option Type Description
particleA Particle First Particle
particleB Particle Second Particle
distance number Target Distance
stiffness number Stiffness (0-1)

AxisConstraint

Restricts to one axis.

Option Type Description
axis 'x' | 'y' Axis
value number Fixed Position

Presets: createHorizontalRail(), createVerticalRail()

MinConstraint / MaxConstraint

Minimum/Maximum boundary.

Presets: createFloor(), createCeiling(), createLeftWall(), createRightWall()

Springs

Spring forces between particles.

Class Description
Spring Standard Spring
MinDistanceSpring Minimum Distance
MaxDistanceSpring Maximum Distance

Options:

Option Type Default Description
particleA Particle - First Particle
particleB Particle - Second Particle
restLength number auto Rest Length
stiffness number 0.5 Stiffness
damping number 0.1 Damping

ParticleString

Chain of particles with constraints.

Factory Functions:

Function Description
createRope(opts) Rope (many segments, soft)
createTautLine(opts) Taut Line (stiff)
createChain(opts) Chain (with Springs)

CollisionZone

Zones with special behavior.

Option Type Description
shape 'rect' | 'circle' Shape
behavior ZoneBehavior Behavior on Entry

Behaviors:

Behavior Description
slow Slow Down
accelerate Speed Up
kill Remove Particle
bounce Bounce
attract Attract

ProximityConnection

Draws lines between nearby particles.

Option Type Default Description
maxDistance number 100 Max. Connection Distance
minOpacity number 0 Opacity at maxDistance
maxOpacity number 1 Opacity at Contact
strokeWidth number 1 Line Width

Presets:

Preset Description
network Network Look
constellation Constellation Look
web Spider Web Look

Presets & Factory Functions

Function Description
createDefaultPhysicsWorld() Default World with Gravity
createRandomParticle(bounds) Random Particle
createParticleChain(n, opts) Chained Particles
addFlockingToWorld(world, preset) Add Flocking

Soft Body Collisions

The soft body system (see 004-Shapes) supports shape-to-shape collisions.

Collision Pipeline

┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐
│   Broad-Phase   │ -> │  Narrow-Phase   │ -> │  Response   │
│      AABB       │    │      SAT        │    │   Impulse   │
└─────────────────┘    └─────────────────┘    └─────────────┘

Phases:

Phase Algorithm Description
Broad-Phase AABB Fast bounding box test - filters non-colliding shapes
Narrow-Phase SAT Separating Axis Theorem - precise polygon overlap
Response Impulse Separate shapes + apply elastic bounce

Enabling

import { ShapeStateManager } from '@carstennichte/cc-toolbox';

// Create and configure shapes...
const shapes: ShapeStateManager[] = [...];

// All shapes know all others
const decorators = shapes.map(s => s.getDecorator());
for (const shape of shapes) {
  shape.setCollisionBodies(decorators);
}

Parameter Influence

Parameter Influence on Collision
elasticity Bounce strength (average of both shapes)
stiffness How fast shape stabilizes after collision
damping Dampens collision bounce

Performance Notes

  • All-against-All: With n shapes → n² checks
  • Recommendation: ~20-30 shapes with collision, ~50 without
  • Concave Shapes: SAT only works reliably for convex polygons