Class PhysicsIntegration
Pure utility methods for updating entity state each game tick. Codifies correct unit algebra for Euler/Verlet integration, drag, friction, and collision push-out.
public static class PhysicsIntegration
- Inheritance
-
PhysicsIntegration
- Inherited Members
Examples
// Typical game loop:
var position = LengthPoint2.FromMeters(0, 0);
var velocity = SpeedVector2.FromMetersPerSecond(1, 0);
var dt = Duration.FromSeconds(0.016);
position = PhysicsIntegration.Euler(position, velocity, dt);
velocity = PhysicsIntegration.Euler(velocity, AccelerationVector2.FromMetersPerSecondSquared(0, -9.8), dt);
Methods
ApplyDrag(SpeedVector2, double, Duration)
Applies exponential drag to a velocity: velocity × exp(−dragCoefficient × dt).
public static SpeedVector2 ApplyDrag(SpeedVector2 velocity, double dragCoefficient, Duration dt)
Parameters
velocitySpeedVector2Current velocity vector.
dragCoefficientdoubleDrag coefficient (s⁻¹). Higher values decay velocity faster. A coefficient of 0 returns the velocity unchanged.
dtDurationTime step duration.
Returns
- SpeedVector2
Velocity after applying drag.
Remarks
Models linear drag (air resistance proportional to velocity). The exponential decay maintains direction and smoothly decays magnitude toward zero without overshooting.
ApplyFriction(SpeedVector2, AccelerationVector2, double, Duration)
Applies Coulomb (sliding) friction to a velocity, decelerating it toward zero.
public static SpeedVector2 ApplyFriction(SpeedVector2 velocity, AccelerationVector2 gravity, double mu, Duration dt)
Parameters
velocitySpeedVector2Current velocity vector.
gravityAccelerationVector2Gravity vector (used for its magnitude; direction is ignored).
mudoubleFriction coefficient (dimensionless). 0 = frictionless; typical: 0.3–0.8.
dtDurationTime step duration.
Returns
- SpeedVector2
Velocity after applying friction.
Remarks
Friction deceleration magnitude is mu × |gravity|. Applied as an impulse over dt.
If the friction impulse would exceed the current speed, the velocity is clamped to zero (no reversal).
Euler(LengthPoint2, SpeedVector2, Duration)
Advances a position by one Euler step: position + velocity × dt.
public static LengthPoint2 Euler(LengthPoint2 position, SpeedVector2 velocity, Duration dt)
Parameters
positionLengthPoint2Current world-space position.
velocitySpeedVector2Current velocity vector.
dtDurationTime step duration.
Returns
- LengthPoint2
New position after the step.
Euler(SpeedVector2, AccelerationVector2, Duration)
Advances a velocity by one Euler step: velocity + acceleration × dt.
public static SpeedVector2 Euler(SpeedVector2 velocity, AccelerationVector2 acceleration, Duration dt)
Parameters
velocitySpeedVector2Current velocity vector.
accelerationAccelerationVector2Current acceleration vector (e.g., gravity).
dtDurationTime step duration.
Returns
- SpeedVector2
New velocity after the step.
Resolve(LengthPoint2, CollisionManifold)
Resolves a collision by applying the manifold push-out to a position:
position + manifold.PushOut.
public static LengthPoint2 Resolve(LengthPoint2 position, CollisionManifold manifold)
Parameters
positionLengthPoint2Current world-space position of body A.
manifoldCollisionManifoldCollision manifold produced by a shape overlap test.
Returns
- LengthPoint2
New position with the overlap resolved.
Remarks
The push-out is ContactNormal × PenetrationDepth, pointing from the other body toward this one.
Apply this to body A's position to fully separate A from B.
Verlet(LengthPoint2, SpeedVector2, AccelerationVector2, Duration)
Advances position and velocity by one Velocity Verlet step.
Position uses a second-order correction: position + velocity × dt + ½ × acceleration × dt².
Velocity uses the first-order update: velocity + acceleration × dt.
public static (LengthPoint2 position, SpeedVector2 velocity) Verlet(LengthPoint2 position, SpeedVector2 velocity, AccelerationVector2 acceleration, Duration dt)
Parameters
positionLengthPoint2Current world-space position.
velocitySpeedVector2Current velocity vector.
accelerationAccelerationVector2Current acceleration vector.
dtDurationTime step duration.
Returns
- (LengthPoint2 position, SpeedVector2 velocity)
Tuple of (new position, new velocity) after the step.
Remarks
The second-order position update makes Verlet more accurate than Euler for constant-acceleration problems (e.g., projectile motion under gravity). Full Velocity Verlet requires re-evaluating forces after the position update; for the simplified single-acceleration form used here, the velocity result is equivalent to Euler.