In case anyone wonders about that reverse-for loop in updateCircles():
Iterating over an array in reverse allows you to remove items in the same iteration (at the very end of the loop). If you delete an item, the items which follow are downshifted by one which means that their indices also change.
However, this isn't a problem if you iterate in reverse, because you already took care of those items in previous iterations. The item you'll handle next will stay where it is.
This also works nice with unordered lists (or "bags").
I don't know if the OP reads this, but one very minor note about the core of the update loop. From the POV of the circles, it is effectively:
for each circle:
if circle is penetrating:
apply collision impulse
remove penetration
integrate forces (gravity) to update velocity
integrate velocity to update position
for each circle:
render circle
Because interpenetration is resolved before integration, the integration step can cause further interpenetration before rendering.
For this case, the effect of this is probably invisible (I couldn't see it). With slower moving objects, higher gravity, or less elastic collisions, this can cause objects to 'sag' or appear springy. A simple change in order helps:
for each circle:
integrate forces (gravity) to update velocity
integrate velocity to update position
if circle is penetrating:
apply collision impulse
remove penetration
for each circle:
render circle
A very minor thing, but something to remember when doing physics animations.
I do not understand. Since this is executed in a loop, for the circle it looks like ...-penetration-integration-penetration-integration-penetration-integration-... in either version. Why does it matter between which steps the circle is rendered?
Trying to keep the narrative of explanation in the same linear order as the code makes for a surprisingly difficult to understand item. Would be neat to see more "traditional" literate programming techniques applied here.
All of that said, really cool, and seriously thank you for sharing!!
I wonder if the weaving in literate code is one of the things that could only have been invented to deal with Pascal. It is useful to be able to rearrange the presentation even in JavaScript, but I doubt it would be enough of a pain point for people to invent weaving in an alternate history were literate programming was born on more flexible languages.
This looks glitchier than the original for some reason, probably just sheer numbers. Balls bouncing off the bottom of lines that are moving away appear to jump.
would be interesting to plot the probability of a ball going to the right direction against the number of lines, when lines are moving clockwise or vice-versa.
Mostly modern game engines use an entity system[1], which is a form of database (global data, I guess, in as much as any database is).
The main loop then steps through each component (of which physics would be one) and lets it update the entity data for all entities.
This pattern took over from class/inheritance based architectures about 10 years ago.
There have been some suggestions that Functional Reactive Programming is a better approach. I've used it in some prototypes, but I couldn't scale it to engine-size, and I'm not aware of it having been used successfully for a full game engine.
So, this approach is pretty much it. You keep a database of state, then you run a system (the physics system, say) to update that database.
Reminds me of a simple physics system I wrote a couple of years ago [0]. After writing a cloth simulation [1] I figured that all I needed to make them into collidable boxes was to have each dot collide with each line. I went in very very small steps, iterating each thing to ensure I understood it. The code was super verbose and I learned a lot from this about linear algebra, cross products, vector projection etc. I always planned to straighten the code out and do a proper writeup.
I think this is awesome but I think it's a little too spaced out. I like the side-by-side display (gives the code an approachable narrative) but I wish I had to scroll up and down (to remind myself of what's going on) less.
Nice code. Thank you. Are those ball-to-line collisions energy preserving? I believe they are...
However it seems there might be an edge case, where moving a colliding circle until it no longer intersects the line, might cause it to skip past another line. Because of this, the lines should not intersect each other.
Sorry to ramble but I love this sort of stuff. Collision detection is covered well in many game development texts.
Yeah he should be getting the starting & ending position of the ball during the tick, and determining whether that line intersects the other line. If it does, the intersection point should be found and the segment that goes past the line should be reflected over the normal, and the ball placed at the new endpoint of the reflected segment. And, of course, the velocity vector needs to be changed as well.
But... I guess this won't be the first time someone posts bad physics code on the internet and poses it as a good example.
The collisions currently reverse the velocity of the circle relative to the line by subtracting to cancel and then subtracting again to negate.
I found a slightly nicer-looking effect can be gained by making the factor ~1.8 to simulate 20% energy loss in collisions.
Obviously, any magic numbers in the code are not relevant for its purpose of demonstrating a simple mathematical concept in a literary style. I'd love to see more examples of this kind around HN as it's a quick way to learn/refresh the odd concept.
I could have really done with this a few months ago. I was trying to make animations of electrons flowing through wires of variable thickness, and really struggled trying to find examples online. I ended up having a three hour maths lesson with my brother over irc, to get my head around vector maths.
One of the "not good" explanations of this was probably mine (and I agree!) written many years ago [1]. I wish I could remember why my code ended up so much more complex.
Same person that wrote gitlet[1], as seen on HN a few weeks ago. Personally I'm extremely happy to see HN so supportive of well commented and documented code.
I find it far more readable. Anyway, next to where you clicked Annotated Code there's a link for Raw Code which has the comments in-line if you prefer that. You can use an IDE or web editor to get the font colors nice.
Do you also prefer footnotes and sidebars inline when reading articles?
These are standard typographical practices. I do set my comment color to super light so comments don't distract me too much when reading code, but I wish there was a better way.
I love the look of the annotated code. I think it would be particularly useful for documentation.
Are there any tools that can generate this from comments, or perhaps an Eclipse or Visual Studio plugin that shows this type of documentation along with the code?
Very cool. Interesting bit: The outcomes of the falling balls seem to differ every time, which corroborates the fact that any minor change in initial state results in vastly different outcomes.
~~The simulation clock is based on the actual frame rate achieved via requestAnimationFrame().~~
Edit: Actually, it looks like the physics portion takes constant (but implicit) time steps each frame, but the time that a circle enters the simulation is based on the actual frame rate, which means when a given circle appears, the lines could be in a different location from previous runs.
[+] [-] ahoge|11 years ago|reply
Iterating over an array in reverse allows you to remove items in the same iteration (at the very end of the loop). If you delete an item, the items which follow are downshifted by one which means that their indices also change.
However, this isn't a problem if you iterate in reverse, because you already took care of those items in previous iterations. The item you'll handle next will stay where it is.
This also works nice with unordered lists (or "bags").
[+] [-] sago|11 years ago|reply
For this case, the effect of this is probably invisible (I couldn't see it). With slower moving objects, higher gravity, or less elastic collisions, this can cause objects to 'sag' or appear springy. A simple change in order helps:
A very minor thing, but something to remember when doing physics animations.[+] [-] qznc|11 years ago|reply
[+] [-] taeric|11 years ago|reply
All of that said, really cool, and seriously thank you for sharing!!
[+] [-] eru|11 years ago|reply
[+] [-] zifnab06|11 years ago|reply
[+] [-] dubya|11 years ago|reply
[+] [-] amolgupta|11 years ago|reply
[+] [-] spullara|11 years ago|reply
http://jsfiddle.net/yr64fy2o/1/
It is nice to be able to show someone directly how changing the various parameters affects the simulation.
[+] [-] hcarvalhoalves|11 years ago|reply
OT: I'm not a game developer. What are the other patterns - besides the global state and mutation functions - that one can use for a game loop?
[+] [-] sago|11 years ago|reply
The main loop then steps through each component (of which physics would be one) and lets it update the entity data for all entities.
This pattern took over from class/inheritance based architectures about 10 years ago.
There have been some suggestions that Functional Reactive Programming is a better approach. I've used it in some prototypes, but I couldn't scale it to engine-size, and I'm not aware of it having been used successfully for a full game engine.
So, this approach is pretty much it. You keep a database of state, then you run a system (the physics system, say) to update that database.
[1] http://t-machine.org/index.php/2007/09/03/entity-systems-are...
[+] [-] hemdawgz|11 years ago|reply
[+] [-] wingerlang|11 years ago|reply
[0] https://www.youtube.com/watch?v=ud8NirjyLAA
[1] https://www.youtube.com/watch?v=G05M_Y6NQVM
[+] [-] thisjepisje|11 years ago|reply
[+] [-] mikeboydbrowne|11 years ago|reply
[+] [-] glhaynes|11 years ago|reply
Anybody know if there's an easy way to get something like the mobile view on desktop (without spoofing user agents, etc)?
[+] [-] jsprogrammer|11 years ago|reply
[+] [-] Flow|11 years ago|reply
https://www.youtube.com/watch?v=SUQb_Oepa6o
[+] [-] chuckledog|11 years ago|reply
[+] [-] rehevkor5|11 years ago|reply
But... I guess this won't be the first time someone posts bad physics code on the internet and poses it as a good example.
[+] [-] cronin101|11 years ago|reply
The collisions currently reverse the velocity of the circle relative to the line by subtracting to cancel and then subtracting again to negate.
I found a slightly nicer-looking effect can be gained by making the factor ~1.8 to simulate 20% energy loss in collisions.
Obviously, any magic numbers in the code are not relevant for its purpose of demonstrating a simple mathematical concept in a literary style. I'd love to see more examples of this kind around HN as it's a quick way to learn/refresh the odd concept.
[+] [-] adam-f|11 years ago|reply
(but litijs itself is an undocumented hack) http://sparecycles.github.io/litijs?litijs
[+] [-] MarcScott|11 years ago|reply
[+] [-] t3hprogrammer|11 years ago|reply
[1] http://ericleong.me/research/circle-line
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] tombh|11 years ago|reply
[1] https://github.com/maryrosecook/gitlet
[+] [-] moe|11 years ago|reply
Making my eyes jump horizontally across the page every few lines is about the worst you can possibly do for readability.
Just keep the damn comments inline and use colors/font-faces/fold markers to make it readable.
[+] [-] clay_to_n|11 years ago|reply
[+] [-] seanmcdirmid|11 years ago|reply
These are standard typographical practices. I do set my comment color to super light so comments don't distract me too much when reading code, but I wish there was a better way.
[+] [-] pc86|11 years ago|reply
Are there any tools that can generate this from comments, or perhaps an Eclipse or Visual Studio plugin that shows this type of documentation along with the code?
[+] [-] JeremyBanks|11 years ago|reply
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] capex|11 years ago|reply
Edit: Or am I just imagining it?
[+] [-] jsprogrammer|11 years ago|reply
Edit: Actually, it looks like the physics portion takes constant (but implicit) time steps each frame, but the time that a circle enters the simulation is based on the actual frame rate, which means when a given circle appears, the lines could be in a different location from previous runs.