Fixed derivative bug.
This commit is contained in:
parent
da0ca76748
commit
45b919c3ff
66
wave.lua
66
wave.lua
|
@ -59,6 +59,7 @@ end
|
||||||
--Derivative of the interpolation.
|
--Derivative of the interpolation.
|
||||||
local Derivative = function( wave, x )
|
local Derivative = function( wave, x )
|
||||||
local re, im = wave.dftre, wave.dftim
|
local re, im = wave.dftre, wave.dftim
|
||||||
|
local y = 0
|
||||||
|
|
||||||
for k = 1, N / 2 do
|
for k = 1, N / 2 do
|
||||||
local c, s = k * math.cos( x * k ), k * math.sin( x * k )
|
local c, s = k * math.cos( x * k ), k * math.sin( x * k )
|
||||||
|
@ -76,25 +77,45 @@ end
|
||||||
--Second derivative of the interpolation.
|
--Second derivative of the interpolation.
|
||||||
local SecondDerivative = function( wave, x )
|
local SecondDerivative = function( wave, x )
|
||||||
local re, im = wave.dftre, wave.dftim
|
local re, im = wave.dftre, wave.dftim
|
||||||
|
local y = 0
|
||||||
|
|
||||||
for k = 1, N / 2 do
|
for k = 1, N / 2 do
|
||||||
local c, s = k * k * math.cos( x * k ), k * k * math.sin( x * k )
|
local c, s = k * k * math.cos( x * k ), k * k * math.sin( x * k )
|
||||||
y = y
|
y = y
|
||||||
- c * re[k + 1]
|
- c * re[k + 1]
|
||||||
+ s * im[k + 1]
|
- s * im[k + 1]
|
||||||
- c * re[N - k + 1]
|
- c * re[N - k + 1]
|
||||||
- s * im[N - k + 1]
|
+ s * im[N - k + 1]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return y
|
return y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Bandlimited impulse located at angle theta.
|
||||||
|
local function AliasedSinc( theta, x )
|
||||||
|
local n, d = math.sin( N * 0.5 * ( x - theta ) ), N * math.sin( 0.5 * ( x - theta ) )
|
||||||
|
if d < 0.0001 and d > -0.0001 then return 1.0 end
|
||||||
|
return n / d
|
||||||
|
end
|
||||||
|
|
||||||
|
--Apply bandlimited impulse to wave.
|
||||||
|
local Impulse = function( wave, location, magnitude )
|
||||||
|
local speed = wave.vrad
|
||||||
|
|
||||||
|
for i = 0, N - 1 do
|
||||||
|
speed[ i + 1 ] = speed[ i + 1 ] + magnitude * AliasedSinc( 2.0 * math.pi * i, location )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
local mt = { __index = {
|
local mt = { __index = {
|
||||||
DFT = DFT,
|
DFT = DFT,
|
||||||
Interpolate = Interpolate,
|
Interpolate = Interpolate,
|
||||||
Derivative = Derivative,
|
Derivative = Derivative,
|
||||||
SecondDerivative = SecondDerivative } }
|
SecondDerivative = SecondDerivative,
|
||||||
|
Impulse = Impulse } }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function Wave( )
|
local function Wave( )
|
||||||
local t = {
|
local t = {
|
||||||
|
@ -138,12 +159,26 @@ local function Draw()
|
||||||
love.graphics.setColor( 0, 0, 0, 0.5 )
|
love.graphics.setColor( 0, 0, 0, 0.5 )
|
||||||
love.graphics.circle( "fill", cx, cy, 0.02 )
|
love.graphics.circle( "fill", cx, cy, 0.02 )
|
||||||
|
|
||||||
love.graphics.setColor( 1.0, 0, 0, 0.5 )
|
|
||||||
for k = 0.1, 1.0, 0.1 do
|
for k = 0.1, 1.0, 0.1 do
|
||||||
|
--Interpolant.
|
||||||
|
love.graphics.setColor( 1.0, 0, 0, 0.5 )
|
||||||
th = ( i - 1 + k ) * 2.0 * math.pi / N
|
th = ( i - 1 + k ) * 2.0 * math.pi / N
|
||||||
r = cur:Interpolate( th )
|
r = cur:Interpolate( th )
|
||||||
x, y = r * math.cos( th ), r * math.sin( th )
|
x, y = r * math.cos( th ), r * math.sin( th )
|
||||||
love.graphics.circle( "fill", x, y, 0.01 )
|
love.graphics.circle( "fill", x, y, 0.01 )
|
||||||
|
|
||||||
|
--First derivative.
|
||||||
|
love.graphics.setColor( 0, 1.0, 0, 0.5 )
|
||||||
|
r = 1.0 + cur:Derivative( th )
|
||||||
|
x, y = r * math.cos( th ), r * math.sin( th )
|
||||||
|
love.graphics.circle( "fill", x, y, 0.01 )
|
||||||
|
|
||||||
|
--Second derivative.
|
||||||
|
love.graphics.setColor( 0, 0, 1.0, 0.5 )
|
||||||
|
r = 1.0 + cur:SecondDerivative( th )
|
||||||
|
x, y = r * math.cos( th ), r * math.sin( th )
|
||||||
|
love.graphics.circle( "fill", x, y, 0.01 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -154,6 +189,19 @@ local function Draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Update()
|
local function Update()
|
||||||
|
local t = love.timer.getTime()
|
||||||
|
for i = 1, N do
|
||||||
|
local rxx = old:SecondDerivative( 2.0 * math.pi * (i - 1) / N )
|
||||||
|
cur.vrad[i] = 0.7 * old.vrad[i] + 0.5 * step * rxx
|
||||||
|
cur.radii[i] = old.radii[i] + step * cur.vrad[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
cur:DFT( )
|
||||||
|
|
||||||
|
if love.math.random( 120 ) < 3 then
|
||||||
|
cur:Impulse( 0, 0.2 )
|
||||||
|
end
|
||||||
|
|
||||||
--Deep copy of current state to old state.
|
--Deep copy of current state to old state.
|
||||||
for name, t in pairs( cur ) do
|
for name, t in pairs( cur ) do
|
||||||
for i = 1, 13 do
|
for i = 1, 13 do
|
||||||
|
@ -161,14 +209,6 @@ local function Update()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local t = love.timer.getTime()
|
|
||||||
for i = 1, N do
|
|
||||||
cur.radii[i] = cur.radii[i] + old.vrad[i] * step
|
|
||||||
cur.vrad[i] = cur.vrad[i] - cur:SecondDerivative( ( i - 1 ) / N )
|
|
||||||
end
|
|
||||||
|
|
||||||
cur:DFT( )
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function DetectCollision( px, py, vpx, vpy )
|
local function DetectCollision( px, py, vpx, vpy )
|
||||||
|
|
Loading…
Reference in New Issue