Physics
A two-dimensional port into JavaScript of the popular Traer Physics Library from Processing.
Downloads
25kb
12kb
Or check out the source code on github.
Purpose
There are many great physics engines out there for JavaScript, so why go and make this one? And, more importantly why would I use this?
-
Familiar: The API hails from the popular Traer Physics Library with some additional sugar for quick-and-dirty simulations. Make a couple
Physics.Particle
's, attach aPhysics.Spring
or aPhysics.Attraction
and away you go! -
Convenient: the
Physics
class itself is aPhysics.ParticleSystem
which offers an animation loop for you. Create avar physics = new Physics()
and callphysics.play()
when you want to kick things off. Withphysics.optimize(true)
it will keep track of particles rest state. During this time, when Physics sees that all particles are resting it discontinues its animation loop. - Flexible: Physics source is requirified so you can take what you need. Many physics engine's require their own Vector class, but with Physics you can swap in your own. This is particularly useful for larger projects where Physics is great to get off the ground and can be replaced easily at a later date for a more optimized engine.
-
Light: Clocking in at around
12kb
Physics is featherweight compared to other JavaScript Physics Libraries. - Bottom-line: If you're like me then at the end of the day you just want to make something work. Physics is great for sketching and quick prototyping. It's not meant to be the foundation for your next HTML5 game nor replace other more robust Physics Engines.
Basic Usage
When using Physics
there are a few core concepts that make developing much easier:
-
When you make a
new Physics
, this represents the world in which all simulated interactions take place. -
There are three main inhabitants of this world:
Physics.Particle
,Physics.Attraction
, andPhysics.Spring
. -
Physics
isPhysics.ParticleSystem
with a few helper methods added. See documentation for specifics.
Now knowing this, let's move forward and create some simulations. N.B: All simulations for this section require canvas2d
to draw objects.
Particle in situ
First, we're going to make a new space for physics to take place. This physics will have gravity and we will add a particle to it — when the particle falls out of viewer's sight we'll place it back where it started:
Attraction
The previous example showed physics with gravity, a constant force applied to all particles in the simulation. However, this isn't necessary. Now we'll create a physics without gravity and two particles. Instead of gravitational force we'll define a different type of behavior for the particles to exhibit, attraction:
Notice the particles continue to be attracted to each other.
Spring
Another more tactile behavior is known as a spring. Particles connected via a spring aim to always be at a specified rest distance from each other. In this example we'll create a spring with a rest distance smaller than the distance between the two particles. When the particles arrive at a state of rest, we'll reset the simulation by setting the positions of the particles to their original values:
Examples
We just saw some basic canvas2d
use cases, but Physics
is renderer agnostic. This means that it only stores positions, how you draw those positions and relationships are up to you! In addition there are many other nuances and techniques that Physics
can simulate. Below are just a few examples in different HTML rendering contexts and more advanced simulations to give you an idea:
-
Simulates cloth, drag mouse to change corner position. Demonstrates how to use and draw a grid of
Physics.Spring
's incanvas2d
context. -
Simulates marbles all attracted to one marble. Click and drag to move marble position. Demonstrates how to use
Physics.Attraction
's inwebgl
context. This example also shows how to handle circular collisions of equal mass. -
Simulates the string plucking, akin to acoustic string instruments. Click and drag string. Demonstrates how to use
Physics.Spring
's insvg
context.
Documentation
Physics
- Extends the ParticleSystem class, exposes all primitives of the Physics library, and adds extra logic for convenient updating. If you already have an animation loop running in your app, then it's recommended to use Physics.ParticleSystem. Unless specified methods return the instance for the purpose of chaining.
-
construction
var physics = new Physics();
-
DEFAULT_GRAVITY
Physics.DEFAULT_GRAVITY
The default gravity used during ParticleSystem's construction.
-
DEFAULT_DRAG
Physics.DEFAULT_DRAG
The default drag used during ParticleSystem's construction.
-
Attraction
Physics.Attraction
Exposed reference to the Attraction class.
-
Integrator
Physics.Integrator
Exposed reference to the Integrator class.
-
Particle
Physics.Particle
Exposed reference to the Particle class.
-
Spring
Physics.Spring
Exposed reference to the Spring class.
-
Vector
Physics.Vector
Exposed reference to the Vector class.
-
onUpdate
physics.onUpdate(f)
A function, f, to be invoked when physics is updating.
-
play
physics.play()
Physics
will not begin simulating until you request it to. This is how to do that. It acts as the Request Animation Frame controller. -
pause
physics.pause()
Stops the simulation. This stops all calculations from continuing.
-
toggle
physics.toggle()
Convenient method to toggle between play and paused states. If playing and
toggle
is invoked then the simulation will pause and vice-versa. -
update
physics.update()
Forces physics to update calculations. In particular, call this method to start the animation loop as well as after mouse interactions.
ParticleSystem
- A class that keeps track of all the different aspects of the Physics space. It is responsible for calculating and updating all the particles, springs, attractions, and forces through an integrator. Unless specified methods return the instance for the purpose of chaining.
-
construction
var system = new Physics.ParticleSystem([gravity, drag]);
-
particles
system.particles
An array holding all the particles in the system.
-
springs
system.springs
An array holding all the springs in the system.
attractions
system.attractions
An array holding all the attractions in the system.
-
forces
system.forces
An array holding all the forces in the system.
-
integrator
system.integrator
An instance of the physics integrator. At the time of writing the system only has one integrator, Runge Kutta.
-
hasDeadParticles
system.hasDeadParticles
Boolean describing whether the system has dead particles or not.
-
gravity
system.gravity
A vector describing the x, y constant force in the system.
-
drag
system.drag
The amount of drag in the system.
-
optimize
system.optimize(b)
Method that sets
system.optimized
property. This enforces whether the system should keep track of if all inhabitants are resting or not. -
setGravity
system.setGravity(x, y)
Convenience method to set gravity of the system.
-
tick
system.tick()
Update the integrator, call this on an animation loop.
-
needsUpdate
system.needsUpdate()
Checks all springs and attractions to see if the contained particles are inert / resting and returns a boolean.
-
addParticle
system.addParticle(p)
Convenience method to add a passed particle, p, to the system.
-
addSpring
system.addSpring(s)
Convenience method to add a passed spring, s, to the system.
-
addAttraction
system.addAttraction(a)
Convenience method to add a passed attractions, a, to the system.
-
makeParticle
system.makeParticle(m, x, y)
Returns a created particle with mass, m, and positions x, y. This also adds the particle to the system.
-
makeSpring
system.makeSpring(a, b, k, d, l)
Returns a created spring which is added to the system. The spring has rest length, l, drag, d, strength, k, and acts between particle a and particle b.
-
makeAttraction
system.makeAttraction(a, b, k, d)
Returns a created attraction between vectors a and b with strength, k, and drag, d. This method also adds the attraction to the system.
-
clear
system.clear()
Removes all particles, springs, and attractions from the system.
-
applyForces
system.applyForces()
Calculates and applies forces within the system.
-
clearForces
system.clearForces()
Clear all forces attached to all particles in the system.
Particle
- A class that holds the current state of a particle. It's position, velocity, force exerted, etc.. Unless specified methods return the instance for the purpose of chaining.
-
construction
var particle = new Physics.Particle([mass])
-
position
particle.position
A vector representing the x, y position of the particle.
-
velocity
particle.velocity
A vector representing the x, y velocity of the particle.
-
force
particle.force
A vector representing the x, y force on the particle.
-
mass
particle.mass
-
fixed
particle.fixed
A boolean describing whether the particle reacts to forces, springs, and attractions. If it doesn't then it is fixed.
-
age
particle.age
A number describing the age of the particle.
-
dead
particle.dead
A boolean describing whether the particle is dead or not. This is not related to inertia.
-
distanceTo
particle.distanceTo(p)
Returns the distance between two particles.
-
makeFixed
particle.makeFixed()
Make the particle fixed in two-dimensional space. Clears its velocity, but not forces.
-
reset
particle.reset()
Sets all properties of the particle to initial values. This is 0 for all values except mass which is 1.
-
resting
particle.resting()
Returns a boolean describing whether the particle is in movement.
Attraction
- A class that holds information about the attraction or repulsion between two particles. Unless specified methods return the instance for the purpose of chaining.
-
construction
var attraction = new Physics.Attraction(a, b, k d)
-
a
attraction.a
A reference to a particle, a.
-
b
attraction.b
A reference to a particle, b.
-
constant
attraction.constant
The strength of the attraction. If constant < 0 then the attraction is considered a repulsion.
-
on
attraction.on
A boolean that describes whether the attraction is enabled within the system.
-
distanceMin
attraction.distanceMin
The minimum distance, radial threshold, before the two particles begin attract.
-
distanceMinSquared
attraction.distanceMinSquared
The minimum distance squared. Used mainly as a pre-calculated value for faster ParticleSystem calculations.
-
update
attraction.update()
Updates the referenced particles forces on each other.
-
resting
attraction.resting()
Returns a boolean describing whether the attraction is inert or not.
Spring
- A class that holds information about a spring between two particles. Unless specified methods return the instance for the purpose of chaining.
-
construction
var spring = new Physics.Spring();
-
a
spring.a
A reference to a particle, a.
-
b
spring.b
A reference to a particle, b.
-
constant
spring.constant
The strength of the attraction between the two particles. If constant < 0 then the attraction is considered a repulsion.
-
damping
spring.damping
The damping value for velocity calculations.
-
on
spring.on
A boolean that describes whether the attraction is enabled within the system.
-
length
spring.length
The acceptable and desired rest length between the two particles.
-
currentLength
spring.currentLength()
Returns the distance between the two referenced particles in two-dimensional space.
-
update
spring.update()
Updates the forces of the two referenced particles acting on each other.
-
resting
spring.resting()
Returns a boolean describing whether the spring is resting or not. Convenient for knowing whether or not the spring needs another update tick.
Integrator
- A class with iterative methods for the approximation of solutions of ordinary differential equations. This particular integrator is based on the Runge Kutta Methods.
-
construction
var integrator = new Physics.Integrator();
Vector
- A class that has x, y positions and a number of convenient methods for executing calculations and operations against them. Unless specified methods return the instance for the purpose of chaining.
-
construction
var vector = new Physics.Vector([x], [y]);
-
x
vector.x, vector.x = 1.0
The x-position of the vector.
-
y
vector.y, vector.y = 1.0
The y-position of the vector.
-
set
vector.set(x, y)
Set the x and y properties of a vector.
-
copy
vector.copy(v)
Set the x and y properties of a vector based on another vector, v.
-
clear
vector.clear()
Set the vector's x and y properties to 0.
-
clone
vector.clone()
Return a new instance of Vector with the same x and y properties as the one invoking the method.
-
add
vector.add(v1, v2)
Set the value of x and y properties to the sum of the first vector, v1, and the second, v2.
-
addSelf
vector.addSelf(v)
Add the passed vector's, v, x and y properties to the vector invoking the method.
-
sub
vector.sub(v1, v2)
Set the value of x and y properties to the difference between the first vector, v1, and the second, v2.
-
subSelf
vector.subSelf(v)
Subtract the passed vector's, v, x and y properties to the vector invoking the method.
-
multiplySelf
vector.multiplySelf(v)
Multiply the passed vector's, v, x and y properties to the vector invoking the method.
-
multiplyScalar
vector.multiplyScalar(n)
Multiply the passed number, n, to both x and y properties of the vector invoking the method.
-
divideScalar
vector.divideScalar(n)
Divide the passed number, n, to both x and y properties of the vector invoking the method.
-
negate
vector.negate()
Used to invert a vector, effectively calling
vector.multiplyScalar(-1)
. -
dot
vector.dot(v)
Returns the dot product of the vector with the passed vector v.
-
lengthSquared
vector.lengthSquared()
Returns the length of the vectored squared.
-
length
vector.length()
Returns the length of the vector.
-
normalize
vector.normalize()
Returns the unit vector of the vector invoking the method.
-
distanceTo
vector.distanceTo(v)
Returns the distance between the vector and the passed vector, v.
-
distanceToSquared
vector.distanceToSquared
Return the distance between the two vector's squared.
-
setLength
vector.setLength(n)
Normalizes the vector and then multiplies the vector's x and y properties by the amount, n.
-
equals
vector.equals(v)
Returns true if the distance between the two vector's is less than 0.0001 — almost the same position.
-
lerp
vector.lerp(v, t)
Linearly interpolate between the vector invoking the method and the passed vector, v, by percentage t. Great for animating.
-
isZero
vector.isZero()
Returns true if the length of the vector is less than 0.0001 — almost zero, zero.
common
-
An object that contains utility methods for class inheritance, optimized JavaScript iterating, and definitive property checking. All methods are cherry picked from underscore.js. While
the file is common, the exported object is referred to as
_
because of its lineage. Warning: this is only accessible if you are using the requirified library. -
each
_.each(list, iterator, [context])
Iterates over a list (array, object, or function) with native forEach if available. A fast for statement.
-
extend
_.extend(obj, *obj)
Pass in a series of objects in which the first object passed will inherit all properties of subsequent objects. If two objects have the same property the latter's property is inherited.
-
indexOf
_.indexOf(array, item, [isSorted])
Given an array returns the index of the item. If not found returns -1.
-
identity
_.identity([value])
A singleton function that returns whatever's passed. Used as an empty function when invoking arbitrary properties of an object or class.
-
isNumber
_.isNumber(obj)
Returns true if the obj passed is a number, otherwise false.
-
isFunction
_.isFunction(obj)
Returns true if the obj passed is a function, otherwise false.
-
isUndefined
_.isUndefined(obj)
Returns true if the obj passed is undefined, otherwise false.
-
isNull
_.isNull(obj)
Returns true if the obj passed is null, otherwise false.
Credits
Physics is not possible without these great contributions to JavaScript:
-
RequireJS
Script dependency management in JavaScript.
-
Underscore.js
Utility functions.
-
Three.js
Default Vector class.
-
Node.js
Build procedures.
-
dat.GUI
Build procedures.