Pool table's Physics


Introduction

PoolTable project using the workbench.

Overall goal:

We would like to give a feeling of real physics law on a virtual environment. We would like to have "real-time" responses, therefore we are trying to use a simple, efficient and "nice behaving" physical model. We are taking Brian Mirtich's approach (UC Berkeley): impulse-base modeling. But we did not use any of his work due more to lack of time than interest. Brian's approach may be also too complicated for a real-time environment.

We have made the following assumptions:

We are dealing with "Physics of particules" rather than "Physics of solids". The physical objects we have are:

- poolballs as spheres with mass, center, the vector position of the center of the poolball, vCenter, the velocity of the center and aCenter, the acceleration.

- cue, modeled as an independent sphere, at the tip of the virtual cue. Only this sphere is interacting with the rest of the poolball.

- bumpers, modeled as a rectangle, with minX, maxX, minY, maxY. We are actually using the felt, a rectangle instead of using each bumper (total is 8). This is just due to lack of time and for simplicity. Ideally we would like to have the ball to collide with each bumper rather than just to the bundaries of the pooltable. Practically we the current assumption is sufficient and looks sufficient. For now on we are going to use bumper and felt for the same element

- holes, just modeled as a sphere and displayed as a disk on the top of the felt. We are working in 2D but are displaying in 3D. It is possible and not more difficult to change the 2D modeling to 3D modeling of the physics: all distances are already 3D distances: we need to add 2 more walls (or bumper), the bottom and the top, change friction of rolling to friction of air (more difficult but I worked out the math because I first used air friction before rolling friction).


Architecture of the physics part

The cue is colliding with any poolball at any time. The poolballs are colliding each other and to the bumper (or felt) and to the holes. For any cycle we are updating two distance table:

- one table with moving object to moving object distance

- one table with staying object to moving object distance

The moving objects are the poolballs and the cue, the staying objects are the bumpers-felt, the holes and other elements only used for the graphics but not stored in the table.

If the distance change for positive to negative, then we have detected a collision and we take an action. We have several actions to take depending on the objects:

- Collision cue-poolball,

- Collision poolball-poolball,

- Collision poolball-bumpers-felt.

- Collision poolball-hole

If the distance change from negative to positive we don't take only actions but update our "collision state machine": we are just using flags that keep track of the state of the balls: "in collision" or "not in collision". This is important because it's possible that : at time t1 you detect no collision (distance > 0) at time t2 you detect collision (distance < 0) and take an action and at t3 you are still in collision so if you don't put any state information you may take an other action that cancel the previous one and you won't have any "physical collision".

Motion of the poolball

Translation of the poolball

The poolBall is defined with a center (center: x,y,z), its velocity (vCenter: vx, vy,vz) and its acceleration (aCenter: ax, ay, az), its angular position (gamma) and its angular velocity with respect with the axis perpendicular to the velocity (omega). (v X omega = z). The ball is displayed as a sphere but is physically modeled as a point (no volume) with mass, therefore there is no inertia involved and the rotation comes only from the friction of the ball to the felt and the motion of the ball. We don't take into account spinning.

All positions of the poolball are computed based on the previous postion and based on the previous velocity and acceleration as shown here.

We bound the velocity to avoid "infinite" velocity that we had at the beginning. Just: if |velocity| > |maxVelocity| then velocity is normalized and velocity = velocity * |maxVelocity|.

The Friction we are using is "Coulomb" friction which is a constant factor in the acceleration. We first started with a more complicated model and also less adequate: air friction, where the acceleration is not a constant any more but is a linear function of the velocity.

a = c*v (c is a constant).

In that model, v(t) = K * exp(-c*t), where K embeds the initial velocity. K = v(t0)/ exp(-c*t0).

"Rolling" of the poolball

The rotation of the balls is computed upon the instanteneous linear velocity: omega = z(normal of the felt) X v/radius. This is actually not correct, but partially correct. Ideally we should represent the relative angle of the ball by 3D angles (Euler Angles, quaternion etc). Our rolling is a rotation along the same axis of the ball and the ball is rotated to be positionned in the axis at each change of direction of the velocity vector. It looks good for fast motion of the ball but it does not look good when the balls are colliding very slowly because then you can see what is wrong.

Distance computation

In our project the only geometric objects are spheres and planes. Spheres are used naturally for the poolball and also for the tip of the virtual cue and for the holes. For the fetl-bumper we are using the rectangle (which we could easily extend to rectangoloid in 3D). Therefore the distance computation is sphere-sphere or sphere-plane.

It is important in our case that we have more than a distance between two objects: usually a distance is positive or null only but not negative. Here we extend the distance to be negative as well. For instance if we compute the distance between a sphere and a plane for the poolball/felt-bumper computation: what we really want to do is the compute the distance between the sphere and a half-space.

distance between two poolballs and distance between one poolball and the felt-bumper

For the distance between the poolball and the felt-bumper we started to use the general formula of distance from a point to a plane as follows:

d = |ax+by+cz+K|/(sqrt(x^2+y^2+z^2))

where the plane's normal n ~= (a,b,c), the point P ~=(x,y,z)

and K is computed as follows: P1 ~=(x1,y1,z1) belongs to the plane therefore verifies:

ax1+by1+cz1 + K = 0, which determines K.

The geometry of the bumpers as well as its definition changed quite a bit in the project therefore we decided to stick on a simple version of the bumper and used the felt. But it should not be more difficult to include "real" bumper-ball distance computation now that the table's definition is stable.

Collision cue-poolball

Right now only the tip of the cue is "solid" and has interaction with the poolballs. It's not clear how to transfer the energy of the cue to the poolball. In the first version we were transfering the instantaneous velocity of the cue to the poolball at the collision's time. Then later we added acceleration to our model to take into account the friction of the ball and we "passed" the acceleration too.

There is still a problem of multiple collisions that can occure when the user is pushing the ball and that the direction of the poolball is more difficult to control.

We thought also of using an average velocity and acceleration over 0.5 seconds or so.

Collision poolball-poolball

We are using the theory of conservation of linear momentum (mass*velocity) in an elastic shock. When two particules collides and when the shock is fully elastic no energy is dissipated but the energy is transfered.

Only the normal component of the linear momentum of the spheres are changed and the tangential component remains the same before and after the shock. The shock is said to be impulsive: the forces of the two balls colliding is much greater than any other exterior forces and the shock is very short in time.

So we have to decouple the velocity into a normal component and a tangential component: the normal is along the vector difference of the two centers and the tangential is perpendicular to it. It is possible to change the coeficient of restitution so that the shock is not elastic at all.

Poolball-pooball collision and elastic shock I

Poolball-pooball collision and elastic shock II

Collision poolball-bumpers-felt

We use the same theory but in a different context: the ball only can move and the bumpers can't. When the ball applies a very strong force to the wall of the bumper, the bumper applies in return a reaction force proportional to the ball's force. In a case of an elastic shock, no energy is lost and the tangential componant vt is the same before and after the shock and the nromal component vn is inverted: vn' = -vn.

We could eventually change the coeficient of restitution, but we didn't offer that option, it would be hard though.

Poolball-felt collision adn elastic shock

Tradeoffs: reaction-based system vs predicted-based system.

Limits of the physical model

"There Is No Alternative" ("Tina", Margaret Thatcher). Actually, there are many alternatives...

At the beginning we thought that we would first compute the entire game (at least for each cue intervention) and then display it and iterate. We could have used what other have done the robotics laboratory when they mixed the configuration (position and orientation of the objects) and time to solve the problem in a 7-d space, for instance as done by Tsai-Yen Li in his thesis.

The minor problem was the dimension of the problem: 7-d for each ball, total space is 7*15=105-d, which would have been reduced easily to 3-d per ball (x,y,t), so 3*15=45-d.

We wanted to try Brian's approach instead.

The advantages of the current implementation is that it's conceptually simple and practically simple. Configuration space is nice but is not too intuitive and prediction may take more than real-time and therefore the user would have to wait some time after he/she would have played which is not the spirit of real-virtuality.

Configuration space approach would have been nice because we would have been able to predict when balls collide and therefore help synchronize the network and the sound. It turned out the lag of the network was not the a problem.

Unstable by nature...

Computing the break layout

The break layout is computed from the first ball to the last. It's a pyramid rotated 90 deg. Any 3 balls in contact form a triangle with 60 60 60 deg angle.

Break

After break

After rotation of the table

Code:

Most of the code for the physics is in geomobject.C, geomworld.C, poolball.C, cue.C and some other.

What to do next:

From "easy" to "difficult":

- go from 2-d to 3-d using a rectangoloid as for the bumpers, and add gravity,

- have the felt being non planar but 3-d surface and evolve toward "mini-golf",

- record the play for each new interaction of the cue with the balls and allow a "undo" button,

- replace the ball with animated figure, but the collision detection would still be sphere-like,

- have correct "rolling" with a 3d angle,

- have a more "secure" state-machine collision-reaction data structure,

- change the model from "dynamics of particules" to "dynamics of solid rigid bodies": allow spinning probably using Brian's approach.

- use Tsai-Yen's approach as well for prediction,

- add the air friction or fogg friction and variation of the friction coeficient.

- have the ball correctly enter the hole,

- implement tactile/force feedback (?): you could hold the ball and replace them,

- model more physics,

- start-up a company in virtual-reality !!!


If you have more question on "physics", you can e-mail to Cyprien (cyp@cs.stanford.edu).


See Also: