In the current era of computer programming culture it is rare to see someone implement something totally new. It happens occasionally now but in the 8-bit era everything was new; in the 16-bit era and early 32-bit era many things were new. I’m talking about from about 1980 to 1995. Back then many simple, interesting 2D cellular automata were undiscovered. 3D cellular automata as rich as Conway Life were not known until the late 80s. High resolution images of the Mandelbrot set were new. No one knew what 3D slices of the 4D quaternion Mandelbrot set would look like. And even basic physics simulations were new. I don’t think I saw a simulation of arbitrary 2D polygonal rigid bodies colliding and obeying classical mechanics, with correct moments of inertia, etc., until well into the 1990s. You did not think about it at the time. You didn’t think “This is the first time someone has implemented an accurate simulation of a pinball machine.” but it was a culture of newness. You expected to see firsts even if you didn’t recognize them as firsts.
When this all ended, I don’t know. To some degree it never ended but things have changed. I often blame GPUs for essentially building one typical application of recreational programming into a chip that is included on all modern computers, ushering in an era in which “computer graphics” has come to be defined solely as rendering lit and textured 3D triangle meshes to the screen and thus leaving little oxygen in the room for splines and voxels and whatever was never invented. Also the death of the international demoscene means that strange computational gems you’ve never seen before are no longer one click to some Belgian web site away. In any case, I am thinking about earlier times because I have recently been working on a project that I started thinking about in the 1990s, a project that is somewhat a child of that era of recreational programming and mathematics. At the time I had been implementing billiards simulations and found myself becoming more interested in what the bugs were like than when the simulation worked correctly.
The project is to come up with an internally consistent system of rules for a fictional alternative to Newtonian mechanics applied to frictionless pucks, specifically rules for 2D physics in which forces act along the arcs of circles rather than straight lines — something like an alternate reality billiard ball simulation. “Curvy physics” as I have it in my notebooks from 25 years ago. Before diving into this I’d like to express once more that this project is about making something up; it is an act of invention. I am not trying to simulate anything from the actual world. I will borrow real physics concepts, e.g. momentum, to the extent they are useful but the goal is just to create something interesting not to model anything real. I make the above disclaimer because I have noticed over the years that people who i would expect to be interested in this project often have a surprisingly hard time understanding what the project is.
Basically the project is to come up with something that looks like this:
We can design such a system by lifting the abstract structure of a simple billiard simulation but changing the details. We will adapt the way in which a typical simulation of 2D Newtonian collisions works at the high-level swapping out the low-level calculations. If we neglect spin, friction, and other forces and just want to simulate a totally elastic Newtonian collision of circular pucks of equal mass, if puck A and B collide and both are in motion, we proceed by
- finding the component of A’s momentum vector that is directed at B and B’s at A, calling these A and B’s “impulse vectors”.
- finding the two “residual vectors” by subtracting the impulse vectors from the total momentum vectors.
- resolving the collision by swapping the two impulse vectors
- finalizing A and B’s new momentum vectors by taking the sum of the residual vectors and the swapped impulse vectors e.g. A’s new momentum equals the sum of A’s residual vector and B’s impulse vector.
Steps 1. to 4. above are general enough that they could be applied to curvy physics if the vectors we refer to are “curvy vectors”, if we can determine the impulse curvy vectors of a specific collision — this has two parts, the circle of the vector and the magnitude of the vector– and if curvy vector arithmetic, addition and subtraction, is defined.
I never really considered anything but the following: a curvy vector is a circle, a magnitude, and an orientation — where by orientation we mean clockwise or counter-clockwise. Orientation can be thought of as the sign of the magnitude. The magnitude component could be an angular magnitude or a linear magnitude, which are largely interchangeable, but we choose a linear magnitude so that by definition the linear magnitude is still defined even if a vector’s circle component is degenerate, if the circle has infinite radius i.e. is a line. Note too that the circle component of a curvy vector must have an absolute location. Consider a puck under the influence of a curvy velocity vector. If the circle vector was relative to the puck’s position, as a classical vector is, then if the puck is displaced by the vector at time t1 at time t2 to displace it again along the same circle would require a different vector, but we want the motion of the puck to be circular and governed by a single vector. Thus we define curvy vectors in terms of absolute coordinates, breaking with the classical version here. What this means is that curvy vector arithmetic has to be done in terms of a location. To add two vectors we will need to know where in 2D space we are adding them.
The Circle of an Impulse Vector
When a collision occurs what will be the equivalent of the green line segment in figure 1? We need some notion of “the circular direction” from one puck to another. That is, along which circles do pucks impose forces when they collide? To answer this question we can appeal to our expectations about the behavior of simple systems. Let us decide a priori that we’d like our physics to exhibit the following phenomenon: when a puck travels around a circle c and collides with a stationary puck of the same mass with a center also on c then the colliding puck imparts all of its (curvy) momentum along c, comes to a stop, and the object puck continues traveling on c with the same speed and orientation the colliding puck had had; thus creating a kind of “Newton’s Cradle” effect as below.
To get this behavior we define the impulse circle as the circle that passes through the centers of both pucks and that is tangent to the colliding puck’s circle of revolution. In the Newton’s cradle case above this definition results in the impulse circle resolving to the circle of revolution of the colliding puck as we want. In other cases the situation looks like the following:
In the above puck A travels clockwise along C and collides with B. The black arrow points in A’s instantaneous direction at the moment of collision. The impulse circle then is the circle that is tangent to the black arrow at the center of A and that also passes through the center of B. If we look at the circle of impulse for all possible centers of B, in the mathematical literature such circles are said to comprise a “parabolic pencil of circles” about the center of A.
This definition of impulse circles implies a couple of differences with the classical case. One consequence is that there is no single circle that is analogous to the green line segment in figure 1. A imposes a circle on B and B imposes a different circle on A, if both A and B are in motion. This is because the circle that passes through two given points with given tangent lines at those points is over determined; such a circle may happen to exist but generally doesn’t. I believe there is always an ellipse that passes through two points and is tangent to given lines at those points and if so perhaps one could invent a curvy physics in which vectors are shaped like arcs of ellipses rather than circles but this whole project is a forking path of such choices and my interest currently is finding the best system that only involves circles.
Another consequence of this definition of impulse circles is that the behavior of the object puck after a collision is dependent on the (curvy) direction in which the colliding puck had been traveling. This is unlike the classical case. Under Newtonian physics if the eight ball is located at some point p relative to a given pocket, where one must aim to sink the ball in the pocket is dependent only on p; where one must aim is independent of the location of the cue ball. Under curvy physics this is not the case, where one must aim depends on the location of the object ball and on the particular arc that the cue ball traverses to get to it.
The Magnitude of an Impulse Vector
The next question is what is the magnitude of the impulse vector? We need a function that determines how much momentum is transferred from puck to puck on a collision. If we assume the pucks are unit circles, the momentum transfer function will be a function of the angle of the collision relative to the colliding puck’s instantaneous direction and the colliding puck’s radius of revolution. The function needs a radius because if we want the newton’s cradle-like behavior above we need the momentum transfer function to return 1 when the angle is such that the impulse circle a puck imposes is the same as a puck’s pre-collision radius of revolution. Further we want the momentum transfer function to return 0 if the angle of the collision is completely oblique — if it just glances the object puck, if what I am calling the angle of collision is a right angle. If we let alpha equal the angle of collision at which the impulse circle is the puck’s radius of revolution — this works out to alpha = atan(2 / sqrt( -2 + 4 r^2)) for unit circle pucks — then three given cases are as below.
Unlike defining impulse circles, I can find no momentum transfer function that is elegant and feels compellingly right. There are many options. The simplest is to make a piecewise function that maps [-pi/2, … , alpha] to [0, … ,1] and [alpha, …, pi/2] to [1, … , 0] via linear interpolation. A more complicated approach is to use inversive geometry: taking A’s center as the origin, invert B’s center about a particular circle that turns A’s circle of revolution into a line passing through the origin and use the cosine of the angle between that line and the line between the origin and the inverted point. Both of these functions work. The circle inversion based one ends up being a function that looks much like cosine between -pi/2 and pi/2 but skewed so that the maxima of 1 occurs at alpha rather than zero. (some Mathematica plots below)
In practice in a simulation of curvy physics however neither of these behave the way we want. The trouble is that the relationship between theta and the radius of the impulse circle is particularly nonlinear. It after all goes to infinity when theta is zero because in this case the impulse circle is degenerate; thus around theta equals zero the function is growing extremely quickly. This results in the momentum transfer function we seem to need also being extremely non-linear. Slow, roughly linear functions like linear interpolation or skewed cosine end up returning close to 1 for too big of a range of collisions, only returning values like 0.5 or 0.6 etc. too close to -pi/2 or pi/2. This results in pretty much every collision imparting all momentum and leaving the colliding puck stationary.
So we need the momentum transfer function to be nonlinear. We want something that is roughly hyperbolic. An elegant function to try is just the ratio between the circle of revolution and the impulse circle choosing the numerator and denominator such that the ratio ends up less than one. We also need zeros at -pi/2 and pi/2 so we subtract the minimum possible impulse circle radius from the numerator and denominator . This function looks like the following;
the two maxima occur when theta is such that the impulse circle in both clockwise and counterclockwise orientations is the same size as the circle of revolution. The zero at zero means that no momentum would be passed to a puck if the impulse circle is degenerate. The maxima when the puck imposes a circle of opposite orientation and the valley around zero are both problematic in that impulse circles larger than a puck’s circle of revolution are not unusual and shouldn’t be treated specially. There is also no reason to treat a degenerate impulse circle specially. I thus choose to use a piecewise function in which I stretch the left-hand side of the above such that the two maxima are stitched together as below
This function behaves the way I want but is ugly in its Frankenstein-like definition. I haven’t found anything better unfortunately.
The following video is a visualization of the eight curvy vectors involved when two pucks, both with velocities, collide — puck A and puck B’s initial vectors, their impulse and residual vectors, and their final vectors post-collision — as the position of B changes relative to A. I have not yet explained how the residual vectors are derived via vector subtraction or how the final vector is derived via addition. I will explain curvy vector arithmetic in part 2 of this post.