A couple of months ago, I spent a few weeks playing with <canvas>. The main reason was to write a game (currently on the back burner, but not "cold" as yet), and also to re-learn some simple mechanics and trigonometry I've forgotten since c.1993. I've put together a little bit of code ("testbed") which lets me put together simple interactive diagrams. Due to the lack of text support in <canvas>, unfortunately I can't label everything diligently. My old maths teacher, Mr. Slatter, would be horrified.
I mainly got sidetracked trying to calculate the scalar, or mass moment of inertia of an arbitrary polygon. This would be used to calculate what happens when something hits a polygon. Unfortunately, I couldn't find any pertinent information about it, and a lot of conflicting (or just plain wrong) stuff confusing it with other things with similar names. I even rootled through the garage and found my trusty 3rd Edition of Stroud, which got me through A-level maths. Anyway, I finally found the answer and then took a break from the code. I should really get back to it sometime.
After seeing some experiments done by my friend Martin, I've thrown caution to the wind and decided to publicise my egregious lack of mathematical knowledge, along with my hacky approach to non-browser-portable Javascript. So, below is a cut-n-paste list of the experiments... comments are extremely welcome.
These pages are simple Javascript experiments with various geometric situations to try things out.
They are most likely to work in Firefox, but will probably run fastest in Opera if at all. Safari is okay, as is Camino.
- Experiment 1: Intersection between a stationary circle and a polygon. Comparison of line normals against direction to intersection points gives whether the circle is inside or outside the polygon. Uses the circle/line intersection test.
- Experiment 2: Collision of circle in motion against a line. Uses similar triangles to work out collision "time", and then reflects both C and C-prime in the line to give new positions for constraints.
- Experiment 3a: Intersection of a circle in motion against a polygon, including corners. Uses two methods: similar triangles technique for collision against edges, and circle/line intersection test for collision against corners. Uses the first collision, using simple minimum finding.
- Experiment 3b: As above, but using simpler algorithms.
- Experiment 4: Oliver Humpage kindly wrote some PHP code simulating a simple collision between a point and a polygon. I've translated this to the same framework I've used here.
- Experiment 5: First step in calculating mass moment of inertia (MMI): triangulation of simple (but not necessarily convex) polygon using Ear Cutting. This is non-optimal, but since the search for a simpler mechanism an open problem, I'm okay with going for the O(n2) solution since we're only doing this once (as long as the polygon doesn't change shape), and we're only doing it for a small n.
- Experiment 6a: MMI test, using bh3/36, which doesn't seem right. Comparison circles are also given. One problem here is confusion between (scalar) {mass,polar,area} moments of inertia, probably thanks to structural engineers making a mockery of the terminology. In particular, I think the author of this page has picked the wrong one (possibly "area" rather than "mass"). Wikipedia's not helpful on this point, and my calculus isn't really up to the task. Finding a formula for the MMI around the centroid of a triangle (in 2D) is proving difficult. I'm not sure if this value will even help: the parallel axis theorem only works for axes in the plane of the shape, while we're trying to get it around an axis normal to the plane of the shape.
- Experiment 6b: The above method doesn't seem to work, so trying a different method. Seems to work well, although the figures go weird when the triangle is "inverted", ie. the vertices are anticlockwise.
- Experiment 6c: Brute force approach, by gridding the triangle and treating each point as a point mass. This should give an approximation for comparison of the other experiments. Interestingly, there seems to be a relationship between the approximation and the largest (pale blue) circle (bounding circle around the centroid). For an equilateral triangle, the approximation is about half that of the circle, and for a sliver-like oblique triangle, it's about 27%. I suspect the range might be ¼ to ½, in inverse relation to the largest angle of the triangle (60°⇒½, 180°⇒¼), but not necessarily inverse proportional. The sliver, of course, tends to that of a thin rod, given by (ml2)/12. As the rod has no area (our current analogue for mass), it gets tricky.
- Experiment 6d: To compare the results of 6b and 6c. Seems to match very well.
- Experiment 7: Combines Experiment 5 with Experiment 6d to demonstrate the use of the MMI calculations on the arbitrary simple polygon. The methods are functionized, and also parameterized to allow a different rotation axis point to the triangle's centroid: in this case, the polygon's centroid. It demonstrates that the method from Experiment 6b is correct and general enough to use for the polygon. This confirms the mass moment of inertia of a simple polygon around an axis normal to the plane of the polygon and through its centroid!
- Verlet Experiment: Test of point-based verlet integration mechanism. Simulates all objects as point meshes. Too slow for use in a Javascript-based game, I think.
- Mandelbrot: To demonstrate to Steve how canvasses work. WARNING: Runs badly in anything but Opera.