Annotated code: Circles bouncing off lines
annotated-code.maryrosecook.com
annotated-code.maryrosecook.com
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").
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.In the linked version we are doing
... move, draw, de-overlap, move, draw, de-overlap ...
So the move might cause an overlap, which we'd draw on screen. Having objects routinely interpenetrating a little (by a frame's worth) can appear springy, as if they aren't made of rigid material.
Better would be
... move, de-overlap, draw, move, de-overlap, draw ...
All of that said, really cool, and seriously thank you for sharing!!
For me, prototype setup and async stuff seemed to naturally lead me to want to differ in the ordering between how I write and how the program is laid out. I find it quite liberating to not care what order I write the code in, dashing off a substitution section to deal with later.
I know functions can be used to chunk out code in different orders, but I like the interplay of having it ordered in the writing in a sensible fashion while still getting the compiled view of it in the programmatic ordering.
Plus my version allows for a lot of finely tuned hacking on the language. That is, one can reduce a lot of boiler-plate setup with processing small chunks of code.
Having said all that, I would not use Knuth's original version for js. I think what was particularly attractive was a simple language like markdown for embedding code in a natural and simple way.
My main repo is https://github.com/jostylr/literate-programming though I am currently rewriting the engine behind it to allow for more asynchronous compiling https://github.com/jostylr/literate-programming-lib
To be honest, I was mostly thinking of Haskell when I wrote my comment. (Semi-) Literate programming is quite popular in their world, and Haskell gives you great flexibility out of the box to order your code. (And even there, having a more flexible order can help, but it's not as urgent.)
qznc makes a great argument for weaving different languages.
http://jsfiddle.net/yr64fy2o/1/
It is nice to be able to show someone directly how changing the various parameters affects the simulation.
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?
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...
As for the implementation, it is extremely simple. For anyone interested just do a search for "verlet cloth".
EDIT: I'd specifically recommend this one [0]. It looks quite simpler than many on youtube but it feels more real.
Anybody know if there's an easy way to get something like the mobile view on desktop (without spoofing user agents, etc)?
doco.css:202
> /* ---------------------- Low resolutions (> 320px) --------------------- */
> @media only screen and (min-width: 320px) {
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 OPs code is fine. And was written by a she, not a he.
Your suggestion is what is sometimes called 'continuous' collision detection. It is needed in some cases, particular when the OP approach might miss collisions (less often for when knock-on-collisions are missed, since those are rarer). But that approach is not 'better' - it is far more time consuming (vastly more for 3d rigid bodies with angular velocity), and has a visual benefit in some cases (not in the OPs case - or at least you wouldn't see the difference).
But, of course, both approaches are very approximate and only intended to give the right feel. If you wanted to be even more accurate you would process your collisions by subdividing updates around the collision (a good pool-ball simulation does this, to model proper breaks). And you'd have to use different integrators than the 1st degree Newton update.
This process can keep going as far as you like. For physics systems I've worked on for modelling the behavior of rigid components in MotoGP bikes, the kinds of approximations you allow are very different to the physics engines I've built for commercial games. Neither are 'better' or 'worse' - a good programmer understands the requirements of their domain . To that extent, the OP's approach is fine, and powers the vast majority of the physics in current generation video games (most engines do support continuous collision detection, but it will be switched off for most rigid bodies in a scene, for performance).
while (trig.isLineIntersectingCircle(circle, line)) {
physics.moveCircle(circle);
}You bring up a slightly different issue now, which I'm not sure if you are suggesting the problem is with the unbounded loop or with the serial strategy for resolution.
On the former, I agree with in the narrow (interpenetration resolution isn't usually guaranteed to converge), but taking
while (has_interpenetration()) {
resolve_interpenetration();
}
and adding a limit for (int i = relaxation_steps; i > 0 && has_interpenetration(); --i) {
resolve_interpenetration();
}
gives you code that is in most game physics engines, in some form.On the latter, modern game engines do some steps globally, rather than just running through each rigid body (often collision detection, interpenetration resolution, resting contact resolution, but not normally collision resolution or integration). But the OP approach of running everything in series wasn't unusual 15 years ago when game physics systems started to become ubiquitous. Before companies like Mathengine and Havok perfected LCP approaches, folks like Ipion and FastCar were doing impulse-based calculations that were heavily serial. So for a very simple JS experiment, it didn't strike me as a problem. I'd have written it that way too, if it were me.
Of course, this is what physics engines do, and why you should probably use one instead of reinventing the wheel.
In terms of showing how a game loop and really basic game physics works, however, this is a pretty clean and understandable 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.
(but litijs itself is an undocumented hack) http://sparecycles.github.io/litijs?litijs
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.
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.
It helps if the inline commentary is differently colored or in a separate box.
I also use light colors for comments when reading source code, but I personally prefer this over having them as footnotes or sidenotes.
Programming should move out the typographical stone age into something a bit more modern.
In the article, I'm assuming the left column takes up a bit less space on the author's browser viewport, but it takes up about 45% of mine, while a bit of the code trails off the page.
The reason I think it works so well with physical books is that the dimensions are known and not user-configurable, so it's easier to guarantee that the sidenotes look appropriate. With free-form comments that could range from a one-line comment to large paragraphs to explain one line of code, I don't think there's a way to make sure they would look reasonable in all cases. (I could be wrong)
A good example of easy-to-read in-text notes (in my opinion) are those in Fred Hebert's LYSE [1]. They could be sidenotes or footnotes, but instead they're in-text, which makes them easier for me to read in a browser, regardless of screen size, but also pretty easy to skip over since they're color-coded and in their own box.
I think it's more of a medium difference than a book-typography-is-more-modern one. When scrolling through a web page or code, I mostly find the single-column in-text notes/comments easier to use, though I see why some people might prefer sidenotes.
[1] http://learnyousomeerlang.com/starting-out-for-real#bool-and...
It is like parenthetical statements in prose: you can't really make them disappear, they are right their in your face. It is considered bad style if they aren't extremely brief, otherwise you should use a foot or side note.
class Widget
{
/**
* @access public
* The name of the widget
*/
public $name;
/**
* @access private
* The widget's material composition
*/
private $composition;
// ... yada, yada ...
}
Even with syntax highlighting on, it can be a pain in the ass to see the code through all that comment noise. I guess I should take the time to configure my folding more.No. I prefer them at the bottom (that's why they're called footnote) and with a tooltip for convenience.
I don't see how that relates to the idiotic idea of scattering comments/code over two wide columns.
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?
Edit: Or am I just imagining it?
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.
Where can I find out more about cool ways to render comments like this?
tick calls requestAnimationFrame, tick returns, the browser waits for the next frame and calls tick...
Is the code annotation page a library?
http://jashkenas.github.io/docco/
There's different ways to configure the output and layout...the Docco homepage uses a single-column format, whereas the OP uses the double-column format.