Improved quadratic function solver; added wrapper for math.sqrt()
parent
a86677b42f
commit
ad0713547c
|
@ -398,13 +398,22 @@ function advtrains.decode_pos(pts)
|
|||
return vector.new(dec(strx), dec(stry), dec(strz))
|
||||
end
|
||||
|
||||
-- Solve quadratic equations (i.e. a*x^2 + b*x + c = 0)
|
||||
function advtrains.solve_quadratic_equation(a, b, c)
|
||||
if not (a and b and c) then return nil end
|
||||
if a == 0 then return {-c/b, -c/b} end -- avoid division by zero
|
||||
local delta = (b*b - 4*a*c)
|
||||
if delta < 0 then return nil end
|
||||
if delta < 0 then return {-b/2/a,-b/2/a} end -- ignore imaginary part
|
||||
return {((-b+math.sqrt(delta))/2/a),((-b-math.sqrt(delta))/2/a)}
|
||||
end
|
||||
|
||||
-- safe square root
|
||||
-- Negative return values indicate imaginary numbers.
|
||||
function advtrains.safesqrt(a)
|
||||
if a >= 0 then return math.sqrt(a) end
|
||||
return 0 - math.sqrt(-a)
|
||||
end
|
||||
|
||||
--[[ Benchmarking code
|
||||
local tdt = {}
|
||||
local tlt = {}
|
||||
|
|
|
@ -94,7 +94,7 @@ LZB point itself, and not related to the emergency brake.
|
|||
]]
|
||||
function advtrains.lzb_map_entry(train, lzb)
|
||||
local ret = {[0]={},[1]={},[2]={},[3]={}}
|
||||
if (not train) or (not lzb) then return ret end
|
||||
if not (train and lzb) then return ret end
|
||||
local ti = train.index
|
||||
local v0 = train.velocity
|
||||
local v1 = lzb.spd
|
||||
|
@ -168,7 +168,7 @@ function advtrains.lzb_get_limit_by_entry(train, lzb)
|
|||
local s = train.index - lzbmap[ret.lever].i
|
||||
local a = advtrains.get_acceleration(train, ret.lever)
|
||||
local v0 = lzbmap[ret.lever].v
|
||||
ret.velocity = math.sqrt(2*a*s - v0*v0)
|
||||
ret.velocity = math.abs(advtrains.safesqrt(2*a*s - v0*v0))
|
||||
end
|
||||
if ret.velocity < train.velocity -1 then ret.lever = ret.lever - 1 end
|
||||
return ret
|
||||
|
|
|
@ -434,7 +434,7 @@ function advtrains.train_step_b(id, train, dtime)
|
|||
else s = (v1*v1 - v0*v0)/2/a
|
||||
end
|
||||
train.ctrl.lzb = nil
|
||||
if lzblimit.velocity and lzblimit.velocity < train.velocity then
|
||||
if lzblimit.velocity and lzblimit.lever < train.lever then
|
||||
tmp_lever = lzblimit.lever
|
||||
while (lzbmap[tmp_lever].t > dtime) do
|
||||
tmp_lever = tmp_lever - 1
|
||||
|
@ -457,7 +457,7 @@ function advtrains.train_step_b(id, train, dtime)
|
|||
a = (v1 - train.velocity)/dtime
|
||||
--- 4b. Move train and update train properties ---
|
||||
local pdist = train.path_dist[math.floor(train.index)] or 1
|
||||
local distance = s / pdist
|
||||
local distance = pdist == 0 and s or s / pdist
|
||||
train.lever = tmp_lever
|
||||
train.velocity = v1
|
||||
train.acceleration = a
|
||||
|
|
Loading…
Reference in New Issue