Upload
oscar-dixon
View
219
Download
3
Embed Size (px)
Citation preview
Let’s Bounce!or
Physics of Collisions Part 1
Games Fundamentals© by Jarek Francik
Kingston University, London
2007 - 2013
What’s on the Agenda?
• Collisions: Elastic vs. Inelastic• Essential Physics:
Momentum, Impulse, Kinematic Energy, Conservation Rules
• Perfectly Inelastic Collision• Elastic Collisions
– Collision with a Stationary Object– Collision between Bills
• Coefficient of Restitution• Implementation Remarks
Elastic vs. Inelastic Collisions
• Physicists classify collisions as:– perfectly inelastic:
– perfectly elastic:
Elastic vs. Inelastic Collisions
• Real collisions are neither perfectly elastic nor inelastic: they are somewhere in-between
• Marbles, bills and many other hard objects may be quite well simulated as perfectly elastic collisions
Elastic Collisions
• Equal mass marbles exchange their velocities:
v‘A = vB v’B = vA
Elastic Collisions
• Maths behind the marbles of different mass is a bit more complex
Elastic Collisions
• But hitting a stationary obstacle, again, is very simple:
v’ = -v
Essential Physics
Momentum, Impulse, Energy
• Momentum
m – massv – velocity
• Impulse
• Kinematic Energy
mvp
pJ
2
2mvEK
2nd Newton’s Law
t
pF
pmv
mt
vF
amF
Two equivalent formulas:
F = am F = Dp / t = J / t
J = Ft
this is how it is widely
known today this is what Isaac Newton
originally wrote
Conservation of Momentum
F1 = -F2 (3rd Newton’s law)
Dp1 / t = Dp2 / t
Dp1 = Dp2
Conservation of Energy
In an Isolated System ENERGY is constant
but
may be converted, for example into heat
Only perfectly elastic collisions conserve the Kinematic Energy.In all real collisions part of Kinematic Energy is lost as colliding objects become hot.
Physics of Perfectly Inelastic Collision
Perfectly Inelastic Collision
before the collision:
vmm
mv
vmmvm
pp
21
1
211
'
')(
'
vmmvmp 121 0
')(' 21 vmmp applying momentum conservation:
after the collision:
Physics of Perfectly Elastic Collision
Perfectly Elastic Collision
Perfectly Elastic Collision
?'
?'
''
'
2
1
22112211
v
v
vmvmvmvm
pp
applying momentum conservation:
after the collision:
before the collision:2211 vmvmp
2211 ''' vmvmp
Elastic collision• Two unknown velocities• Momentum equation is not enough, we
need something more!
• Definition:Elastic colision is a colision in whichthe kinematic energy is conserved
constmv
Ek 2
2
Elastic collision
21
111222
21
222111
22112211
222
211
222
211
2)('
2)('
''2
'
2
'
22
mm
vmmmvv
mm
vmmmvv
vmvmvmvm
vmvmvmvm
Elastic collision of equal masses
source: http://en.wikipedia.org/wiki/Elastic_collision
11
21
1122
2222
1
21
21
111222
21
222111
2
22)('
2
22)('
2)('
2)('
vm
mv
mm
vmmmvv
vm
mv
mm
vmmmvv
mmmif
mm
vmmmvv
mm
vmmmvv
Elastic Collisions
• collision with a stationary object:
marbles bouncing from the walls
• bills bouncing from each other :billiard (or snooker) game
Collision with a Stationary Object
x’v
y’vv’
f
Collision with a Stationary Object
xv
yv v
f
f
f
vv
vv
yy
xx
'
'
v
v’
Collision with a Stationary Object
x’v
y’vv’
f
xv
yv v
f
f
f
NOTICE:CHANGE OF SYMBOLS
NOTICE:CHANGE OF SYMBOLS
vv
vv
yy
xx
'
'
Collision with a Stationary Object
v’
v’||
v’
f
vv||
v
f
ff
xv
x’v
yv
y’v
||'||
'
vv
vv
),( vv yxv
),( nn yxn
n
'? v
||','? vv
||,? vv1n
c
1c
n: normal vector
c: collision vector
),(),( nncc xyyxc
n
c
Collision with a Stationary Object
v’
v’||
v’
f
vv||
v
f
ff
xv
x’v
yv
y’v
||'||
'
vv
vv
),( vv yxv
),( nn yxn
'? v
||','? vv
||,? vv1n
1c
n: normal vector
c: collision vector
),(),( nncc xyyxc
Collision with a Stationary Object
)()('
)()('
)(
)(
nvycvyy
nvxcvxx
yyxxcv
yyxxnv
xyyx
ncv
ncv
cvcv
nvnv
ncnc
v’
v’||
v’
f
v
v
f
ff
xv
x’v
yv
y’v
nv||
c
||'||
'
vv
vv
),( vv yxv
),( nn yxn
)( nvnv
)(|| cvcv
)(' nvnvv
)(' |||| cvcvv
)()(''' || nvncvcvvv
),(),( nncc xyyxc
Collision with a Stationary Object
)()('
)()('
)(
)(
nvycvyy
nvxcvxx
yyxxcv
yyxxnv
xyyx
ncv
ncv
cvcv
nvnv
ncnc
||'||
'
vv
vv
),( vv yxv
),( nn yxn
)( nvnv
)(|| cvcv
)(' nvnvv
)(' |||| cvcvv
)()(''' || nvncvcvvv
),(),( nncc xyyxc
Collision with a Stationary Object
)()('
)()('
)(
)(
nvycvyy
nvxcvxx
yyxxcv
yyxxnv
xyyx
ncv
ncv
cvcv
nvnv
ncnc
||
'||
'
vv
vv
),( vv yxv
),( nn yxn
)( nvnv
)(|| cvcv
)(' nvnvv
)(' |||| cvcvv
)()(''' || nvncvcvvv
),(),( nncc xyyxc
double xv = ball.GetXVelocity();double yv = ball.GetYVelocity();double xn =
sin(DEG2RAD(obj.GetRotation()));double yn =
cos(DEG2RAD(obj.GetRotation()));double xc = -yn;double yc = xn;double vdotn = xv * xn + yv * yn;double vdotc = xv * xc + yv * yc;ball.SetVelocity(xc * vdotc - xn *
vdotn, yc * vdotc - yn * vdotn);
Physics of the Billiard/Snooker Game
Billiard Gamet
v
changenovvvv
exchangevvvv
||2||2||1||1
1221
''
!''
c nv
v||
),( 1212 YYXXt
R
tn
2 ),( nn xyc
)( nvnv )(|| cvcv
)()('''
)()('''
21||21||222
12||12||111
cvcnvnvvvvv
cvcnvnvvvvv
)()('
)()('
212
121
cvcnvnv
cvcnvnv
Billiard Game
// distance vector (t) and radiusdouble xt = ball2.GetPrecX() -
ball1.GetPrecX();double yt = ball2.GetPrecY() -
ball1.GetPrecY();double R = ball1.GetWidth();
// normal and collision vectorsdouble xn = xt / 2 / R;double yn = yt / 2 / R;double xc = -yn;double yc = xn;
// velocity vectorsdouble xv1 = ball1.GetXVelocity();double yv1 = -ball1.GetYVelocity();double xv2 = ball2.GetXVelocity();double yv2 = -ball2.GetYVelocity();
// dot productsdouble v1dotn = xv1 * xn + yv1 * yn;double v1dotc = xv1 * xc + yv1 * yc;double v2dotn = xv2 * xn + yv2 * yn;double v2dotc = xv2 * xc + yv2 * yc;
ball1.SetVelocity(xn * v2dotn + xc * v1dotc, -(yn * v2dotn + yc *
v1dotc));ball2.SetVelocity(xn * v1dotn + xc * v2dotc, -(yn * v1dotn + yc *
v2dotc));
)()('
)()('
212
121
cvcnvnv
cvcnvnv
),( 1212 YYXXt
R
tn
2 ),( nn xyc
)( nvnv )(|| cvcv
Billiard GameLife Demo
Coefficient of Restitution
General Case
• Newton’s Law of Restitution
e – coefficient of restitution
Notice that we use relative velocityand relative normal velocity:
nevnv '
nvvnv
vvv
)( 21
21
evv '
Implementation Remarks
1.Ball Sinking
2. Bouncing & Sinking: a simple solution for balls and boxes
Ball Sinking in the Floor
In the real world:
before hit! after
Ball Sinking in the Floor
In the simulated world:
before hit! after
Ball Sinking in the Floor
or even a worse scenario:
before hit! after
WRONGBounce condition may be wrongly detected!
SOLUTION: only bounce when moving DOWN
Ball Sinking in the Floor
General solution:
only apply the bounce if v • n > 0
v
n
Ball Sinking in Another Ball
Ball Sinking in Another Ball
• In the real world:
before hit! after
Ball Sinking in Another Ball
• In the simulated world:
before hit! after
Ball Sinking in Another Ball
• In the nasty case:
#1 #2 #3
In frame #3 the balls still overlap. This may lead to repeated application of the ‘bounce’ effect. The balls may end up ‘glued’!
Ball Sinking in Another Ball
• In the nasty case:
no collision yet
frame #1
Ball Sinking in Another Ball
• In the nasty case:
collision detected
frame #2
Ball Sinking in Another Ball
• In the nasty case:
collision detected
bouncing applied
frame #2
Ball Sinking in Another Ball
• In the nasty case:
collision detected (again!)
frame #3
Ball Sinking in Another Ball
• In the nasty case:
collision detected (again!)
bouncing applied
frame #3
WRONG
Ball Sinking in Another Ball
• Solution:
Take:- t: position vector (of the other ball)- v: velocity vector
if (v ∙ t < 0) don’t bounce!
frame #3t
v
Ball Sinking in Another Ball
• Solution:
frame #3
Take:- t: position vector (of the other ball)- v: velocity vector
if (v ∙ t < 0) don’t bounce!
// distance vector (t) and radiusdouble xt = ball2.GetPrecX() -
ball1.GetPrecX();double yt = ball2.GetPrecY() -
ball1.GetPrecY();double R = ball1.GetWidth();
// normal and collision vectorsdouble xn = xt / 2 / R;double yn = yt / 2 / R;double xc = -yn;double yc = xn;
// velocity vectorsdouble xv1 = ball1.GetXVelocity();double yv1 = -ball1.GetYVelocity();double xv2 = ball2.GetXVelocity();double yv2 = -ball2.GetYVelocity();
// dot productsdouble v1dotn = xv1 * xn + yv1 * yn;double v1dotc = xv1 * xc + yv1 * yc;double v2dotn = xv2 * xn + yv2 * yn;double v2dotc = xv2 * xc + yv2 * yc;
ball1.SetVelocity(xn * v2dotn + xc * v1dotc, -(yn * v2dotn + yc *
v1dotc));ball2.SetVelocity(xn * v1dotn + xc * v2dotc, -(yn * v1dotn + yc *
v2dotc));
t
v
Ball Sinking in Another Ball
• Solution:
frame #3
Take:- t: position vector (of the other ball)- v: velocity vector
if (v ∙ t < 0) don’t bounce!
// distance vector (t) and radiusdouble xt = ball2.GetPrecX() -
ball1.GetPrecX();double yt = ball2.GetPrecY() -
ball1.GetPrecY();double R = ball1.GetWidth();
// normal and collision vectorsdouble xn = xt / 2 / R;double yn = yt / 2 / R;double xc = -yn;double yc = xn;
// velocity vectorsdouble xv1 = ball1.GetXVelocity();double yv1 = -ball1.GetYVelocity();double xv2 = ball2.GetXVelocity();double yv2 = -ball2.GetYVelocity();
// check velocity dot positiondouble vx = xv1 - xv2;double vy = yv1 - yv2;if (vx * xt + vy * yt < 0)
return;
// dot productsdouble v1dotn = xv1 * xn + yv1 * yn;double v1dotc = xv1 * xc + yv1 * yc;double v2dotn = xv2 * xn + yv2 * yn;double v2dotc = xv2 * xc + yv2 * yc;
ball1.SetVelocity(xn * v2dotn + xc * v1dotc, -(yn * v2dotn + yc *
v1dotc));ball2.SetVelocity(xn * v1dotn + xc * v2dotc, -(yn * v1dotn + yc *
v2dotc));
t
v
• Bouncing from boxes and walls is quite common in games – simple and advanced
a scene from the Marble,
a workshop task for today...
Bouncing & Sinking: a simple solution for balls & boxes
• GFC offers an effective hit test function for rectangular sprites against circular shapes, for which position and radius are known:
rect.HitTest(pos, radius);
Bouncing & Sinking: a simple solution for balls & boxes
• Problem:when the ball is overlapping the box it is too late to determine which side it entered (why?)
Bouncing & Sinking: a simple solution for balls & boxes
• Solution:track the previous frame position.
Bouncing & Sinking: a simple solution for balls & boxes
• Example:the ball is hitting the left hand edge of the box if:– there is a hit in frame #n– it was to the left of the box in frame #n-1
Bouncing & Sinking: a simple solution for balls & boxes
• Solution Draft:1. Store in a safe place the position of the ball before the
update. This should be the position after the previous frame, before the current one – (x0, y0)
2. Just after update, check the HitTest. If there is no collision there is no bounce.
3. Now, when we know there is a hit:• Assume there was no hit with (x0, y0)*
• Check on which side of the box the ball was (in the prev frame)• Apply the appropriate bounce• Amend the position of the ball so that to prevent sinking
* this assumption will be satisfied if you prevent sinking!
Bouncing & Sinking: a simple solution for balls & boxes
• Here is the solution:1. Store in a safe place the position of the ball before
the update. This should be the position after the previous frame, before the current one – (x0, y0)
2. Just after update, check the HitTest. If there is no collision there is no bounce.
3. Now, when we know there is a hit:• Assume there was no hit with (x0, y0)*.
• Check on which side of the box the ball was.• Apply the appropriate bounce.• Amend the position of the ball so that to prevent sinking.
* this assumption will be satisfied if you prevent sinking!
let’s have a look at thispoint in greater detail...
Bouncing & Sinking: a simple solution for balls & boxes
Decompose ball’s velocity into vx and vy
• if vx > 0 the ball was travelling rightwardsand we only check the left side of the box
• if vx < 0 the ball was travelling leftwardsand we only check the right side of the box
• if vy > 0 the ball was travelling upwardsand we only check the bottom side of the box
• if vy < 0 the ball was travelling downwardsand we only check the upper side of the box
Bouncing & Sinking: a simple solution for balls & boxes
Decompose ball’s velocity into vx and vy
• if vx > 0 the ball was travelling rightwardsand we only check the left side of the box
• if vx < 0 the ball was travelling rightwardsand we only check the left side of the box
• if vy > 0 the ball was travelling upwardsand we only check the bottom side of the box
• if vy < 0 the ball was travelling downwardsand we only check the upper side of the box
Bouncing & Sinking: a simple solution for balls & boxes
Decompose ball’s velocity into vx and vy
• if vx > 0 the ball was travelling rightwardsand we only check the left side of the box
if (vx > 0 && x0 + r <= pWall->GetLeft()){
vx *= -damp; // bounce with dampingx1 = pWall->GetLeft() - r; // amend the position
// (to prevent sinking)
}// Repeat for remaining three sides...// and, finally, apply all the changestheBall.SetVelocity(vx, vy);theBall.SetPosition(x1, y1);
Bouncing & Sinking: a simple solution for balls & boxes