71 lines
2.0 KiB
Lua
71 lines
2.0 KiB
Lua
local function Polar( x, y )
|
|
local arctan = math.atan2( y, x )
|
|
--maybe we don't need this line?
|
|
--if arctan < 0.0 then arctan = arctan + 2.0 * math.pi end
|
|
return math.sqrt( x * x + y * y ), arctan
|
|
end
|
|
|
|
local function tPolar( t )
|
|
return Polar( t.x, t.y )
|
|
end
|
|
|
|
local function LerpWave( cur, new, alpha, x )
|
|
local a = cur:Interpolate( x )
|
|
local b = new:Interpolate( x )
|
|
return alpha * b + ( 1.0 - alpha ) * a
|
|
end
|
|
|
|
--Peak of alpha * cur + (1 - alpha) * new on interval [xi, xf]
|
|
local function GetMinimum( cur, new, alpha, xi, xf )
|
|
local ri, rf = LerpWave( cur, new, alpha, xi ), LerpWave( cur, new, alpha, xf )
|
|
local xm = 0.5 * ( xi + xf )
|
|
local rm = LerpWave( cur, new, alpha, 0.5 * ( xi + xf ) )
|
|
return math.min( ri, rf )
|
|
end
|
|
|
|
local function GetTimeFromAlpha( alpha, curM, newM )
|
|
return alpha * newM.t + ( 1.0 - alpha ) * curM.t
|
|
end
|
|
|
|
local function DetectCollision( curMarble, newMarble, curWave, newWave )
|
|
local t, dt, r, th, normal
|
|
|
|
|
|
--Polar coordinates:
|
|
local iRadius, iTheta = tPolar( curMarble )
|
|
local fRadius, fTheta = tPolar( newMarble )
|
|
local iWaveRadius = curWave:Interpolate( iTheta )
|
|
local fWaveRadius = curWave:Interpolate( fTheta )
|
|
|
|
local speed = newMarble.dx * newMarble.dx + newMarble.dy * newMarble.dy
|
|
|
|
--Case 1: marble is already outside the curve.
|
|
if iRadius > iWaveRadius then
|
|
return {
|
|
speed = speed,
|
|
dt = newMarble.t - curMarble.t,
|
|
t = curMarble.t,
|
|
r = iWaveRadius,
|
|
th = iTheta,
|
|
normal = iTheta - math.atan( curWave:Derivative( iTheta ) ), }
|
|
end
|
|
|
|
--Case 2: marble is outside the curve by tick end.
|
|
if fRadius > fWaveRadius then
|
|
--This isn't right, fix later.
|
|
return {
|
|
speed = speed,
|
|
dt = 0,
|
|
t = newMarble.t,
|
|
r = fWaveRadius,
|
|
th = fTheta,
|
|
normal = fTheta - math.atan( curWave:Derivative( iTheta ) ) }
|
|
end
|
|
|
|
--Case 3: check whether marble passed through analog peak.
|
|
|
|
--Case 4: marble must have remained inside curve.
|
|
return
|
|
end
|
|
|
|
return DetectCollision |