Show HN: A 2D Physics Simulator in JavaScript
htmlpreview.github.io
htmlpreview.github.io
Matter.js: http://brm.io/matter-js/
Cannon.js: http://www.cannonjs.org/
PhysicsJS: http://wellcaffeinated.net/PhysicsJS/
Box2DJS: http://box2d-js.sourceforge.net/ (Emscripten-compiled from flash)
p2: https://github.com/schteppe/p2.js
Ammo.js: https://github.com/kripken/ammo.js/ (Emscripten-compiled from C++)
JPE: https://github.com/colorhook/JPE
Oimo.js: https://github.com/lo-th/Oimo.js/
Planck.js: https://github.com/shakiba/planck.js
Personally i found the linked content to be much more approachable than your links, though they are undoubtedly better physics engines.
PheT also has lots of good stuff: https://phet.colorado.edu/
I've been trying to understand js physics simulation for many years, and this is the first demo that I find understandable. Amazing work!
I also wrote a tutorial on how constraints work (probably the the most difficult part)
Is it deterministic? Does it do destructive updates?
A single step that isn't consistent in behavior across every setup is enough to make the entire process non-deterministic.
This is destructive:
this.position += this.velocityThen you can do whatever you want with that series of immutable instants. You might pass that data structure to a function for rendering, or for storing history, or whatever else. You might even do something clever like pass two consecutive steps into your rendering function, so you can calculate motion blur between them.
Treating each simulation step as an instance of a data structure means you decouple the simulation state and time from your program state and time. Novice programmers often use global variables to hold the state of a simulation or game, but there's a smarter way to do it. You insert a layer of abstraction between your program's control flow and the simulation's time flow.
In Chrome, the fourth box from the top starts sliding when it hits the floor, pushing the box to the right clear off the floor box. Every box eventually slides along the floor and falls into the pit.
In Firefox, the fourth from the top stays put. It never pushes the box on the right, though all the rest eventually slide into the pit.
I think the "neither instance seems to actually make physical sense" is due to a lack of friction.
Friction is a biggie that I need to add ASAP!
Edit: yup, it's the same every time per browser, but I can have e.g. Edge and Chrome running next to one another doing different things.
Floating point is completely deterministic (as you note by getting the same behavior every time you run the simulation in the browser). I'm looking at the js spec, and there shouldn't be any freedom in evaluating floating point expressions (but overly clever browser vendors may have ignored that and reordered them anyhow).
However, I do know for a fact that the implementations of the Math.sin and Math.cos functions are browser specific,
https://tc39.github.io/ecma262/#sec-math.sin
so that alone will remove any chance at browser independent reproducibility, without additional controls.
Be interesting to see if replacing Math.cos and Math.sin with your own implementation would remove the cross browser dependency.
Btw, spec conforming implementation of Math.sin
function sin(x) {
if ( x === Infinity
|| x === -Infinity
|| x === NaN) {
return NaN;
}
return x;
}You can look at the source code and see if that's what it's doing.
So you want to change the simulation? Change the initial setup.
This is obviously not user friendly, but I'm not sure how you can possibly suggest this is not a simulation.
Having always the same animation helps debugging. But yeah I should have added the option to add a mouse!
... does it have conservation of energy? Can you track total energy somehow?
... does it obey approximately some kind of Liouville theorem?
You're going to need a geometric integrator for that, probably an energy-momentum integrator. In practice it is often better to conserve the symplectic form instead of energy, though, and you can show that for fixed time-steps you can't get all of energy/momentum/symplecticity at the same time (I haven't looked at this for a while, a student of the school of Marsden jump in if I'm saying anything wrong). Furthermore, these guarantees all require integrability...
I was asking about these simplified physics engines (in games, etc.) that are probably not deriving physical laws out of whole conservation- (or Noetherian symmetry-) cloth.
The movie folks have larger compute time budgets, and I've seen various geometric integrators used there. I know of at least one studio that uses implicit midpoint for thin shell simulation. The Cal-Tech influence has wormed its way into the graphics research world, at least, and you see some papers pop up there frequently looking at geometric integrators. This Danish guy (I'm forgetting his name) at Disney publishes papers every now and then on the topic.
http://htmlpreview.github.io/?https://github.com/aguaviva/Ph...
this one shows how to solve a double/n pendulum, which is something that is not explained in detail anywhere. So if you want to learn how constraints work that should get you up to speed!
Somehow boxes slide along a flat floor with no deceleration until they fall off the screen
a) physics programs are supposed to offer interactivity. Else whats the point?
b) the physics look unearthly
To solve differential equations for which analytical solutions do not exist?
Edit: Differential inclusions, if inequality constraints are included in the system (as they would here).
Box2D with many more objects consumes 22%.
Oimo, with a 3D rendering scene with TONS of objects: 35% CPU..
Matter.js, lots of objects with mouse interaction: 15% CPU.
Plank, lots of objects: 25%
I'm wondering how/why this ended up in the front page...