Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Show HN: A 2D Physics Simulator in JavaScript (htmlpreview.github.io)
126 points by xchip on July 27, 2017 | hide | past | favorite | 62 comments


Why is this upvoted so much? In what way is it better than any of the existing JS physics engines?

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


All those are great physics engines. Mine is just very simple and easy to understand, hopefully it inspires other people to get into the world of simulations.


Also thanks for the reference to Erin Catto's talk, need to check it out. Maybe physics engines aren't magic after all.


In fact that was one of the reasons that compelled me do write my own, because physics engines looked to me like voodoo magic. Thanks for understanding my obsession with learning :)


It doesn't take into account surface friction? Those boxes seem covered in soap to me.


This is a Show HN; you don't need to be entirely novel to have things to show.

Personally i found the linked content to be much more approachable than your links, though they are undoubtedly better physics engines.


Because it does something cool and people find it interesting. Doesn't take away from existing systems.


To add to the list, the best physics engine I've seen (not for js games, for actual physics simulations to teach people physics) is this one: https://www.myphysicslab.com/

PheT also has lots of good stuff: https://phet.colorado.edu/


I'm with you, and I don't even find this particular example that interesting or accurate. You just re-run the same simulation over and over without any control of the initial or boundary conditions.


What's special about this simulation is that the entire code fits on one page, including linear algebra library: https://github.com/aguaviva/Physics/blob/master/RigidBodyCha...

I've been trying to understand js physics simulation for many years, and this is the first demo that I find understandable. Amazing work!


Fantastic, in fact I wrote because I had been trying to understand physics engines four a long time and it was super hard to follow the papers. I wrote it four learning my self and published it to help others not go through my frustration :)


I used some physics engines. I feel the simulation quality of the one made by op is quit good, even better than some complete engines.


Thanks! :)


If you want to look at precedence or what other people have done successfully in this space check out http://brm.io/matter-js/ matter JS. It's pretty sweet.


pretty cool and inspiring!


It features collisions, collisions response and hinges-constraints.

I also wrote a tutorial on how constraints work (probably the the most difficult part)


Cool!

Is it deterministic? Does it do destructive updates?


Thanks! What do you mean by deterministic/destructive updates?


No idea what destructive updates are, but determinism is when you can run multiple times in multiple environments and get the same results


then yes, it is deterministic :)


I don't mean to be rude, but if you don't know the term I'd put money on it not being deterministic. Especially if you're running in JavaScript on multiple browsers.

A single step that isn't consistent in behavior across every setup is enough to make the entire process non-deterministic.


Destructive updates are where computing the next step in the simulation destroys or overwrites the previous step.

This is destructive:

    this.position += this.velocity


The alternative being to store a history of the simulation?


The alternative is to treat the simulation as a series of immutable instants. Every step of the simulation is encapsulated and represented as a data structure. So the core loop would look something like nextState = advanceFrame(currentState) , where currentState is immutable and contains every piece of information needed to calculate nextState.

Then 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.


Is this really a simulation if you can't modify any of the objects? For all we know, this could all be pre-calculated or pre-animated. Everything moves exactly the same way every time.


It moves differently in different browsers for me. And neither instance seems to actually make physical sense.

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.


In Firefox Developer Edition everything happens faster than in regular Firefox, though they seem to end at the same result. I wonder why that is. Animation doesn't seem much faster.

I think the "neither instance seems to actually make physical sense" is due to a lack of friction.


The animation speed is determined by a timer, this should make it run the same in all the browsers. Is the simulation nice and smooth all the time?

Friction is a biggie that I need to add ASAP!


I suspect you're experiencing the joy of floating-point nondeterminism.

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.


Hey hey hey, let's not blame floating point here ;).

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;     
  }


that is quite strange... the time step is always the same no matter on how the frames are rendered.... the animation should be identical


try using requestAnimationFrame instead of a timer


Awesome, I didnt know about that one (still learning!), thanks!


For me, boxes move underneath other boxes due to the lack of friction. It's the exact same movement every time. I wonder why I'm getting downvoted.


> For all we know, this could all be pre-calculated or pre-animated. Everything moves exactly the same way every time.

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.


:D you are welcome to add objects, make the chain longer or change gravity...

Having always the same animation helps debugging. But yeah I should have added the option to add a mouse!


If you're interested in this kind of stuff, I highly recommend reading or watching something about Ivan Sutherland's Sketchpad.

https://www.youtube.com/watch?v=USyoT_Ha_bA


I knew that one! is fantastic isn't it!? This is one of my favourites: https://github.com/xibyte/jsketcher


Thanks, good show. Another one I like is http://physics.weber.edu/schroeder/html5/. See Newton's cannon etc.


This is where I show that I know nothing about physics engines:

... does it have conservation of energy? Can you track total energy somehow?

... does it obey approximately some kind of Liouville theorem?


> does it have conservation of energy? Can you track total energy somehow?

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...


My (ongoing) thesis is in the field of symplectic integrators.

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.


Very cool! Game rigid body engines (to my knowledge) usually use symplectic Euler (v^{n+1} = v^n + h M^{-1} F^n, q^{n+1} = q^n + h v^n) with a Moreau/Stewart-Trinkle velocity level discretization of non-penetration constraint (effectively impulses), usually lobbing off the quadratic velocity term (so no precession). These constraints are typically solved in a (projected) Gauss-Seidel fashion to horribly loose tolerances, with liberal post-stabilization thrown in. Outside of rigid bodies, for the most part in games, these days, you don't get 'simulations' that can be derived from a variational principle, but that are instead constraint satisfaction problems with some notion of momentum hacked in the side (see 'Position Based Dynamics', 'Shape Matching').

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.


Amazing post!


It is surprisingly difficult to find a concrete explanation of symplecticity. It seems like https://en.m.wikipedia.org/wiki/Symplectic_integrator has links to all the relevant information, but even there the conserved quantity is given as a differential form dp /\ dq, which makes me wonder whether you can even compute it for individual points, or whether you have to integrate over the whole space.


The contact link just says <my_github_account_username>@gmail.com. I'd love to look at some actual code if there's a github link?


There is code and there is also some quick tutorials on how constraints work,

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!



Is there friction or non-zero restitution?


There is no friction so far but I will add it whenever I have a chance!


The only part missing? Physics...

Somehow boxes slide along a flat floor with no deceleration until they fall off the screen


I think the word you were looking for was "friction". This certainly looks like a simulation that a physics professor would propose on a chalk board: "Ignoring friction for the purpose of this exercise..."


Erm, no offense but:

a) physics programs are supposed to offer interactivity. Else whats the point?

b) the physics look unearthly


> physics programs are supposed to offer interactivity. Else whats the point?

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).


Of course it depends on what the goal of the program is, but something like this should offer user interactivity. By solving whatever is necessary (or faking it).


a) I know, that is still WIP :) b) There is no friction, and as Newton's First Law states "an object will remain at rest or in uniform motion in a straight line unless acted upon by an external force" :)


Hey, again no offense meant. I just think the whole point of something like this is to mimic the real world. And after a couple of seconds my illusion is broken. Ps. It is cool, just needs to be cooler :)


ahah, no worries it will get there! In the meanwhile you have to give me also some "suspension of disbelief" for the sake of enjoyment :D


hehe. Best of luck dude! :D


The link is for interactive demos.


Out of curiosity: The chrome tab running the engine is using 55% of my CPU, an i7-4770K running at 3.5Ghz...

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...


Physics engines are like magic and it is pretty hard understand how the work even if you read the paper many times. Also physics engines are interesting not only because four the dynamics, but also for the way constraints are solved. There are many other problems were you could apply this same techniques. This JavaScript engine it's a couple of pages long, it's easy to understand and potentially could give you a new vision on how to solve problems. The reason why is uses do much CPU time is because the collision detection algorithm compares every single pair of objects, to speed up that part I'd need to add what is called a 'broad phase' but that would complicate the code and the point was to write clear code and leave the low hanging fruit for the reader.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: