Dynamics3D
3D analog of Dynamics. Continuous-time dynamics primitive for agents on a ContinuousVolume; owns the per-agent 3D velocity state and the list of Force3Ds contributing to motion. The step method performs the Euler integration step (sum forces → integrate velocity → compute candidate position) without applying it; the caller decides what to do with the candidate (wrap onto a 3D torus, reject if it enters a no-fly zone, clamp altitude to ground/ceiling, accept as-is).
Typical use (drone flight):
val dynamics = Dynamics3D<Drone>(airspace).apply {
addForce(desiredVelocity3D(speed = 5.0, tau = 0.5) { d, dyn ->
val p = dyn.space.positionOf(d) ?: return@desiredVelocity3D Point3D.ORIGIN
flow.directionAt(p)
})
addForce(peerRepulsion3D(radius = 3.0) { d -> 50.0 / d })
maxSpeed = 8.0
}
while (true) {
val (vNew, pNew) = dynamics.step(drone, dt = 0.1)
dynamics.setVelocity(drone, vNew)
airspace.moveTo(drone, clampToAirspace(pNew))
delay(0.1)
}For the common "no boundary handling needed" case use runDynamics3D. For walls / no-fly zones / altitude clamps, write your own loop around step.
All Defaults and maxSpeed / minSpeed validation works exactly as in 2D Dynamics.
Parameters
the 3D projection that owns agent positions
per-agent mass function. Default is unit mass for all.
Constructors
Types
Mutable global defaults for Dynamics3D. Mirrors Dynamics.Defaults.
Properties
Number of forces currently registered.
Lower bound — velocities below this magnitude are rescaled back up to minSpeed. A body at exactly zero velocity is given a deterministic heading (a pure function of its identity, so runs stay reproducible) and boosted to minSpeed too. Set to 0 to allow agents to stop. Must be non-negative and <= maxSpeed.
Functions
Set / update the velocity tracked for agent.
Compute one Euler step for every agent in agents without applying any of them — a Jacobi (synchronous) update. Every step reads the current shared state, so the result is independent of the order of agents, unlike calling step and applying per agent in a loop (a Gauss-Seidel update that depends on iteration order). The caller applies the returned triples.
Get the current velocity tracked for agent, or null if not set.