This is by far the most complex physics interaction we have to deal with and cannot be accurately modelled with such a simple calculation as the cue-ball, ball-table and ball-ball cases.

]]>This is by far the most complex physics interaction we have to deal with and cannot be accurately modelled with such a simple calculation as the cue-ball, ball-table and ball-ball cases.

The naïve approach here would be to treat the balls and cushions like light hitting a mirror, where the path of the ball is reflected with equal angles from the cushion, perhaps with some speed reduced to account for energy lost in the reaction. This is a good first approximation and good way of aiming shots off cushions when playing, however it doesn't capture all of the desired behaviour, such as vertical spin imparting movement parallel to the cushion or vice versa.

With the ball-ball collisions we treated the balls as 'rigid bodies'; they do not deform and the period of time of the collision is vanishingly small. However the cushions are made of rubber and do deform when the balls hit them, this is what makes them so bouncy. Hence any simple rigid body calculation we make will not correctly model this interaction.

It is worth noting that although the cushions do deform, the collision still happens over a small time frame compared to what we are capable of perceiving with our eyes. Indeed the interaction is at most about 1/60 seconds long. Since this is also the amount of time each frame is displayed for on a smartphone it makes no sense to try and display this deformation on the screen. Therefore we can still treat the cushions as rigid bodies in our physics engine when it comes to collision detection, but we must calculate the collision response as a special case.

As the ball hits the cushion its velocity can be described as a 2‑vector v_{0} =〈v_{0x}, v_{0y}〉(assuming no vertical movement) and its angular velocity as a 3‑vector ω_{0} =〈ω_{0x}, ω_{0y}, ω_{0z}〉where x and y are along the surface of the table and also parallel and perpendicular to the direction of the cushion respectively. The same goes for the ball as it is leaving the cushion with velocity v_{1} and angular velocity ω_{1}. Thus we need a set of equations for v_{1} and ω_{1} in terms of v_{0} and ω_{0}. My first approach was to use a combination of intuition and empirical observation to write rough equations here that felt approximately correct to real snooker and pool. These are fast to calculate and easy to adjust if a situation is found that is really off, however they can't hope to fully simulate the real behaviour especially when not backed up by data.

The best effort to calculate the ball-cushion behaviour I have found is Mathavan, Jackson and Parkin's paper A theoretical analysis of billiard ball dynamics under cushion impacts. The authors present a model which considers the simultaneous ball contacts at the cushion and at the table and a constant coefficient of restitution (in terms of energies) and sets up a set of differential equations. These differential equations are then solved with a numerical solver. The authors had previously done work with a high speed camera to calculate the ball cushion interaction for a small set of input parameters (v_{0x}=0, ω_{0x}=‑v_{0y}/r, ω_{0y}=0, ω_{0z}=0), they then used this knowledge to calibrate the constants in their set of equations.

I recreated their results in my physics engine. It would be very computationally expensive to run the numerical solver every time a ball hits a cushion so the values for various input parameters are precalculated on my desktop computer and written to a file which the game then loads and can read from. Values which haven't been precalculated can be interpolated from the surrounding values.

This is the model I currently use in my games and it works well. It has a solid underlying physical bases and provides plausible results. I wish the authors had presented more work to validate the results with a wider variety of different input parameters.

There are however situations where this model does not seem to work well, particularly with unusual amounts of spin or at high speeds. I often receive emails, reviews and comments from people who aren't completely satisfied with the physics in these games. This is something I want to rectify with this project. In the next post we will start to look at my plan of how to do this.

]]>There are four main questions when it comes to the laws that govern the physics of a game of pool or snooker. Answering these questions with mathematical formulae that match the real world behaviour of the balls in these situations is key to creating a realistic physics engine.

How does the cue interact with the cue ball?

Initially this was not something I modelled in my engine, essentially I let the player choose the initial movement of the cue ball directly rather than that of a physical cue that strikes the ball. However this approach excludes some interesting behaviour, for example in real life when the cue ball is hit on its left or right side its path is deflected slightly to the opposite side, this is known as 'squirt'. The model I currently use for this reaction can be found here however it is not something I have done extensive research on yet to determine its accuracy.

How do the balls move on the surface of the table?

This problem seems to have been first well described and answered by Coriolis in 1835. Assuming the ball isn't airborne it is first in a state of sliding on the table where the contact point of the ball with the table moves relative to the table, then there is a rolling phase where the rotation of the ball is such that the contact point does not move relative to the table before the ball comes to a stop. On top of this the ball can spin on its vertical axis which does not interact with the spin or movement along the other axes.

During the sliding phase there is a frictional force that acts in the opposite direction to the relative moment of the contact point on the table, Coriolis and many others describe this as a constant force thus the ball moves a parabola on the table. This is the model I have used until now in my games, with a coefficient of friction of μ = 0.15, however this is something I want to verify and investigate with this project.

During the rolling phase the frictional force is much smaller and acts in the opposite direction to the movement of the ball thus the ball moves in a straight line. This is also assumed to be constant with a value of μ = 0.009 in my engine. For simplicity of calculation I assume the rolling friction to be negligible during the sliding phase. In this project I also hope to examine the limits of these assumptions and get a more accurate calculation of the frictional constant.

The spin of the ball on its vertical axis is assumed to be independent of all the other movement of the ball on the table surface. In my model it decays linearly over time α = -22 rad/s^{2} until it has stopped spinning on this axis, the ball may still be sliding, may be rolling, or may be stationary at this point. I also look to verify these assumptions in this project.

How do balls interact with each other?

The reaction of two balls hitting each other is modelled as an instantaneous impulse with friction as here. I negate any vertical translation of the ball after impact in my current engine to avoid having to deal with balls leaving the surface of the table in my current engine. I use a coefficient of friction of μ = 0.05 and a coefficient of restitution of r = 0.95 between the balls. Investigating this is probably outside the scope of this project.

In the next blog post we will look at the the final interaction, and the main focus of this project; the reaction when a ball hits a cushion.

]]>In my 'day

]]>In my 'day job' I create pool and snooker games for smartphones. I strive to make the games feel as realistic as possible, while still being fair. One of the biggest challenges is to simulate the physics of the balls. The main challenge of such a game is for the player to anticipate how the all balls will bounce off each other, off the cushions and hopefully into the pockets when a certain impulse is applied to the cue ball. This means that the physics simulation in the game not only must be robust and readable, but it should match players' expectations that they have gained from watching the sport on TV or playing it in real life.

There are many existing 'physics engines' for creating games. While these can be excellent for simulating realistic looking collisions and reactions of objects of all different shapes, sizes and materials, they often fail when it comes to accurately recreating a specific scenario such as this one. The balls move and spin very fast, many collisions can happen in a very short space of time and a single collision being 'missed' or not accurately resolved will be noticed by a player. On top of this 3D physics engines are computationally expensive, and having my games run well on low-end smartphone hardware is crucial. This is why I have created my own custom physics engine. Fortunately this is a lot easier than writing a general physics engine as I only need to deal with the situations that arise in pool and snooker. The only moving objects are spheres, all collisions are between a sphere and either another sphere or a stationary cushion, no objects ever stack on top of each other etc.

There are two main phases to a rigid-body physics engine like this. The first is 'collision detection' where it is calculated whether or not two objects will collide and if so the time at which this happens. The second phase is 'collision response' where the reaction of the colliding objects is calculated, this will be based on the position, speed, rotation and spin of the objects. Collision detection is not in the scope of these posts however the next post will be about the collision response in my pool and snooker physics engine.

]]>An object that does not reflect light that is at a constant temperature emits a spectrum of light according to Planck's law. At different temperatures the shape and intensity of the spectra are different. And so the colour of that object appears to be different.

Drag left and right to

]]>An object that does not reflect light that is at a constant temperature emits a spectrum of light according to Planck's law. At different temperatures the shape and intensity of the spectra are different. And so the colour of that object appears to be different.

Drag left and right to adjust the temperature. The sun is roughly 5800K, the spectrum underneath is the approximate shape of the spectrum of sunlight as it leaves the sun. Different stars are at different tempteratures and appear to be different colours.

Note the spectrum at the bottom is mixed with faint white light (or grey) here. This brings the colours within the renderable space of your screen and you can imagine how the true colours of the spectrum might appear without the grey.

]]>Here we take our spectral colour picker and plot the colours using the CIE xyY colour space.

How much of the space can you explore? What is the shape of explorable space? How do you create the colours on the boundary?

]]>Here we take our spectral colour picker and plot the colours using the CIE xyY colour space.

How much of the space can you explore? What is the shape of explorable space? How do you create the colours on the boundary?

]]>A colour picker with a difference. Drag over the bottom half to paint a spectrum. The colour we perceive from light with these wavelengths at these intensities is shown at the top. The brightest possible intensity of that colour your screen can display is chosen.

Note that some colours can

]]>A colour picker with a difference. Drag over the bottom half to paint a spectrum. The colour we perceive from light with these wavelengths at these intensities is shown at the top. The brightest possible intensity of that colour your screen can display is chosen.

Note that some colours can be created with totally different spectra.

Can you make white light?

]]>Here you can move and resize two different spectra to see how the colours interact.

Dragging left and right moves the position of the spectrum, up and down controls the size.

Drag at the top to move the top spectrum, at the bottom to move the bottom and in the

]]>Here you can move and resize two different spectra to see how the colours interact.

Dragging left and right moves the position of the spectrum, up and down controls the size.

Drag at the top to move the top spectrum, at the bottom to move the bottom and in the centre to move both.

Some quite pretty results are possible.

]]>Hello, I want to do some experiments in colour.

The way we usually treat colour in computer graphics is as a linear combination of red, green and blue components. Indeed this is how it is displayed to us by our screens. However the light that reaches our retina and makes

]]>Hello, I want to do some experiments in colour.

The way we usually treat colour in computer graphics is as a linear combination of red, green and blue components. Indeed this is how it is displayed to us by our screens. However the light that reaches our retina and makes us perceive colour is actually made up of lots of individual photons. Each of these has a wavelength. The different wavelengths activate our light receptors on our retinas to different degrees.

Light from a laser contains photons of only one wavelength. Light from other sources (e.g. the sun) contains photons of varying numbers at all different wavelengths. This is called a spectrum.

The real-time graphic above tries to show the closest colour on your monitor that matches the colour of a laser at each wavelength. The shortest wavelength is on the left [390nm] and the longest on the right [830nm]. I used color matching functions to calculate the tristimulus values then the sRGB specification to translate that into the familiar red, blue and green components for your screen to display.

New CIE XYZ functions transformed from the CIE (2006) LMS functions Wikipedia - sRGB

]]>I'm back, and it's time for something very unsexy. Blue (or Poisson disc) noise is a 2-dimensional noise where every pair of points is at least a certain distance apart. It's very useful for sampling or for generating eye-pleasing patterns. A progressive ranking of a set of points is such

]]>I'm back, and it's time for something very unsexy. Blue (or Poisson disc) noise is a 2-dimensional noise where every pair of points is at least a certain distance apart. It's very useful for sampling or for generating eye-pleasing patterns. A progressive ranking of a set of points is such that any subset of the first n points is also distributed in a blue noise pattern.

I read this paper and was very impressed by the beauty of the approach and the results. I recommend at least watching the video. I have implemented this partially in javascript above.

Drag right and left to alter the number of points.

Coded in javascript using HTML5 canvas (2d) for rendering.

]]>After making the voronoi sphere generator I wanted to show how nice meshes are created if the points are evenly distributed. One way of doing this would be to write a blue noise algorithm. I also wanted to show how the mesh can be dynamic if the points move.

I

]]>After making the voronoi sphere generator I wanted to show how nice meshes are created if the points are evenly distributed. One way of doing this would be to write a blue noise algorithm. I also wanted to show how the mesh can be dynamic if the points move.

I then realised I could show both of these at once by allowing the points to repel each other. The points are moving on the surface of a spher and repelled from each other proportional to the inverse square of the angle between them. There is a constant drag on the velocity which allows the points to settle.

Drag the points around to see the others react. Drag elsewhere to move the camera.

Coded in javascript using HTML5 canvas (2d) for rendering.

Colours from Kuler.

I recently played Polyfauna by Radiohead. Lovely app plus the intro was in this great vector style. It reminded me a lot of Vib-Ribbon.

I thought I'd try my hand at recreating a similar effect. Here it is! I designed the typeface myself (also a new experience).

Tap the screen

]]>I recently played Polyfauna by Radiohead. Lovely app plus the intro was in this great vector style. It reminded me a lot of Vib-Ribbon.

I thought I'd try my hand at recreating a similar effect. Here it is! I designed the typeface myself (also a new experience).

Tap the screen to make everything go 'squiggly'.

Coded in javascript using HTML5 canvas (2d) for rendering.

]]>We were watching a 'making of' where GMUNK was discussing an effect in TRON Legacy. He mentioned using a Voronoi diagram for a geometric shape. Now a simple 2d plane made up of voronoi cells will break if you warp it around, the faces will not remain planar in general.

]]>We were watching a 'making of' where GMUNK was discussing an effect in TRON Legacy. He mentioned using a Voronoi diagram for a geometric shape. Now a simple 2d plane made up of voronoi cells will break if you warp it around, the faces will not remain planar in general. There is a natural 3-dimensional analogue to the Voronoi diagram, with three dimensional cells, but it has a different aesthetic.

Here I have created a natural analogue to the 2d voronoi diagram but on the surface of a sphere. Each of the blue dots generates a plane normal to it and edges and vertices are calculated as intersections between those planes. Edges are equidistant from generating points.

Drag the points around to change the polyhedron. Drag elsewhere to move the camera.

Coded in javascript using HTML5 canvas (2d) for rendering.

Colours from Kuler.

In my last post I showed a toy I made. Although I was happy with what I'd made in a day. It had a bunch of bugs and annoyances I was pretty sure I could sort out with a little more time.

The points could easily get stuck. They didn't

]]>In my last post I showed a toy I made. Although I was happy with what I'd made in a day. It had a bunch of bugs and annoyances I was pretty sure I could sort out with a little more time.

The points could easily get stuck. They didn't move smoothly against each other. It was possible to break the connections by moving things at awkward angles.

My day dedicating to fixing it didn't go as smoothly as hoped, and it's probably not worth spending any longer on the idea. Above is a work in progress that can generate some quite pretty results. I have implemented continuous collision detection and multitouch.

Drag the circles around. When touching they will be connected with a line.

]]>Here's a little toy I made. Drag the blobs around and see how the lines wrap around each other.

I'm really happy with the result. The whole thing was written from scratch, and despite no traditional physics engine or techniques being used the result feels tactile and solid.

If I

]]>Here's a little toy I made. Drag the blobs around and see how the lines wrap around each other.

I'm really happy with the result. The whole thing was written from scratch, and despite no traditional physics engine or techniques being used the result feels tactile and solid.

If I were to spend more time it would be to rewrite a lot of the code to allow for variable line widths, blobs being able to slide past each other rather than just getting stuck and multitouch support.

Coded in javascript using HTML5 canvas for rendering.

Colours from Kuler.

Line-line intersection test from jsPerf.

]]>