From f350f8785c219af2406ec68031e924b4a79b328d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20C?= Date: Mon, 22 Jan 2024 11:06:03 +0100 Subject: [PATCH] Flow routing: Initialize basin_graph + comment where complexity might be non-linear --- terrainlib_lua/rivermapper.lua | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/terrainlib_lua/rivermapper.lua b/terrainlib_lua/rivermapper.lua index 92ab11f..5479d1e 100644 --- a/terrainlib_lua/rivermapper.lua +++ b/terrainlib_lua/rivermapper.lua @@ -111,6 +111,10 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional local d = dirs2[i] -- Get the directions water is coming from -- Iterate through the 4 directions + -- Loop is unrolled on purpose, for performance (critical part!) + ---------- + -- EAST -- + ---------- if d >= 8 then -- River coming from the East d = d - 8 cur = cur + 1 @@ -123,7 +127,7 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional local l2 = basin_links[b2] if not l2 then l2 = {b2, ib, elev=elev, i=i+1, is_y=false} - basin_links[b2] = l2 + basin_links[b2] = l2 -- Potential non-linear complexity here elseif l2.elev > elev then -- If this link is lower than the lowest registered link between these two basins, register it as the new lowest pass l2.elev = elev l2.i = i+1 @@ -146,6 +150,9 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional end end + ----------- + -- SOUTH -- + ----------- if d >= 4 then -- River coming from the South d = d - 4 cur = cur + 1 @@ -180,6 +187,9 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional end end + ---------- + -- WEST -- + ---------- if d >= 2 then -- River coming from the West d = d - 2 cur = cur + 1 @@ -214,6 +224,9 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional end end + ----------- + -- NORTH -- + ----------- if d >= 1 then -- River coming from the North cur = cur + 1 singular[cur] = i-X @@ -287,7 +300,10 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional end local basin_graph = {} - while cur > 1 do + for i=0, nbasins do + basin_graph[i] = {} -- Initialize (to ensure subtables don't go in the hash part) + end + for i=1, nbasins do -- Iterate in lowlevel but its contents may change during the loop local b1 = lowlevel[cur] cur = cur - 1 @@ -307,13 +323,7 @@ local function flow_routing(dem, dirs, lakes) -- 'dirs' and 'lakes' are optional -- Add link to the graph, in both directions local bound = lnk1[b2] local bb1, bb2 = bound[1], bound[2] - if not basin_graph[bb1] then - basin_graph[bb1] = {} - end - if not basin_graph[bb2] then - basin_graph[bb2] = {} - end - basin_graph[bb1][bb2] = bound + basin_graph[bb1][bb2] = bound -- Potential non-linear complexity here basin_graph[bb2][bb1] = bound -- Merge basin b1 into b2