From ad0713547c45930254473d8dc2b198b0587183d2 Mon Sep 17 00:00:00 2001 From: ywang Date: Sat, 7 Dec 2019 16:48:19 +0100 Subject: Improved quadratic function solver; added wrapper for math.sqrt() --- advtrains/helpers.lua | 11 ++++++++++- advtrains/lzb.lua | 4 ++-- advtrains/trainlogic.lua | 4 ++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/advtrains/helpers.lua b/advtrains/helpers.lua index a2eabb5..9afe72d 100644 --- a/advtrains/helpers.lua +++ b/advtrains/helpers.lua @@ -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 = {} diff --git a/advtrains/lzb.lua b/advtrains/lzb.lua index 3961438..30d7972 100644 --- a/advtrains/lzb.lua +++ b/advtrains/lzb.lua @@ -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 diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index 7e9a613..c0c3888 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -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 -- cgit v1.2.3