From 506d81be80365cec0823ec9b1d9402a9bbc805d0 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 23 Feb 2019 16:25:48 -0600 Subject: [PATCH] better drawing --- lua/graph.lua | 2 +- lua/regions.lua | 17 +++++ main.lua | 137 ++++++++++++++++++++++++++++++------- modules/graph_algorithms.c | 7 +- 4 files changed, 135 insertions(+), 28 deletions(-) diff --git a/lua/graph.lua b/lua/graph.lua index 36c2c3e..7806791 100644 --- a/lua/graph.lua +++ b/lua/graph.lua @@ -83,7 +83,7 @@ function Graph:setNodePos(nodeID, x, y) end function Graph:dijkstras(startID, iterations) - graphs.dijkstras(self.graph, startID, iterations) + return graphs.dijkstras(self.graph, startID, iterations) end return Graph \ No newline at end of file diff --git a/lua/regions.lua b/lua/regions.lua index f64cbcc..204e6b0 100644 --- a/lua/regions.lua +++ b/lua/regions.lua @@ -21,6 +21,23 @@ function Regions:add(region) return id end +function Regions:remove(regionID) + local idx = -1 + for i, reg in ipairs(self) do + if reg.id == regionID then + idx = i + break + end + end + + if idx >= 0 then + table.remove(self, idx) + table.sort(self, function(a, b) + return a.priority > b.priority + end) + end +end + function Regions:draw() for i = #self, 1, -1 do local region = self[i] diff --git a/main.lua b/main.lua index dfe843a..a449603 100644 --- a/main.lua +++ b/main.lua @@ -4,40 +4,49 @@ local Regions = require "lua.regions" local graph = nil local regions = nil +local graph_region = nil function love.load() + GRAPH_FONT = love.graphics.setNewFont(16) + graph = Graph:new() graph:addNode(100, 100) graph:addNode(300, 100) graph:addNode(200, 200) graph:addNode(500, 400) - graph:addNode(0, 0) + graph:addNode(300, 300) graph:addArc(0, 1) graph:addEdge(0, 2) - graph:addArc(1, 3) + graph:addArc(1, 3, 99) graph:addEdge(1, 2) - --graph:dijkstras(0, 0) - - love.graphics.setBackgroundColor(0.5, 0.5, 0.5) - regions = Regions:new() - regions:add { + graph_region = { + -- needed for Regions calculations priority = 1; rect = { 200, 0, 600, 600 }; + -- other properties selectedNode = nil; + postDrawFunction = nil; + isMouseDown = false; update = function(self) end; draw = function(self) love.graphics.setColor(0.7, 0.8, 0.9) love.graphics.rectangle("fill", 0, 0, 600, 600) - drawGraph(graph) + drawGraph(graph, self.selectedNode) + + if self.postDrawFunction then + self.postDrawFunction(self) + end end; mousedown = function(self, x, y) + self.isMouseDown = true + self.selectedNode = nil local nodes = graph:getNodes() for _, node in pairs(nodes) do @@ -45,39 +54,90 @@ function love.load() local ny = node.y local d = (x - nx) * (x - nx) + (y - ny) * (y - ny) - if d <= 400 then + if d <= 20 * 20 then self.selectedNode = node.id end end end; mouseup = function(self, x, y) - self.selectedNode = nil + self.isMouseDown = false end; mousemove = function(self, x, y, dx, dy) - if self.selectedNode ~= nil then + if self.selectedNode ~= nil and self.isMouseDown then graph:setNodePos(self.selectedNode, x, y) end end; mouseenter = function(self) end; mouseleave = function(self) - self.selectedNode = nil + self.isMouseDown = false end; } - regions:add { - priority = 0; - rect = { 0, 0, 0, 0 }; + regions:add(graph_region) + + + -- regions:add { + -- priority = 0; + -- rect = { 0, 0, 0, 0 }; + + -- update = function(self) end; + -- draw = function(self) end; + -- mousedown = function(self, x, y) end; + -- mouseup = function(self, x, y) end; + -- mousemove = function(self, x, y, dx, dy) end; + -- mouseenter = function(self) end; + -- mouseleave = function(self) end; + -- } +end + +function createDijskstraStepper() + local step = -1 + + function updateDijkstras() + local dj = graph:dijkstras(0, step) + graph_region.postDrawFunction = function(reg) + drawDijkstras(graph, dj) + end + end + updateDijkstras() + + local reg_id + local region = { + priority = 10; + rect = { 200, 550, 600, 50 }; update = function(self) end; - draw = function(self) end; - mousedown = function(self, x, y) end; + draw = function(self) + love.graphics.setColor(0, 0, 0, 0.7) + love.graphics.rectangle("fill", 0, 0, 600, 50) + + love.graphics.setColor(1, 1, 1) + love.graphics.polygon("fill", 265, 25, 295, 10, 295, 40) + love.graphics.polygon("fill", 335, 25, 305, 10, 305, 40) + end; + mousedown = function(self, x, y) + if x >= 265 and x <= 295 then + step = step - 1 + if step < -1 then step = -1 end + elseif x >= 305 and x <= 335 then + step = step + 1 + end + + updateDijkstras() + if x >= 550 then + regions:remove(reg_id) + graph_region.postDrawFunction = nil + end + end; mouseup = function(self, x, y) end; mousemove = function(self, x, y, dx, dy) end; mouseenter = function(self) end; mouseleave = function(self) end; } + + reg_id = regions:add(region) end function love.mousepressed(x, y, button, isTouch, presses) @@ -96,7 +156,11 @@ function love.update() regions:update() end -function drawGraph(graph) +-- DRAWING FUNCTIONS + +local NODE_INNER_RADIUS = 17 +local NODE_OUTER_RADIUS = 20 +function drawGraph(graph, selectedNode) local nodes = graph:getNodes() local edges = graph:getEdges() @@ -110,13 +174,13 @@ function drawGraph(graph) love.graphics.line(x1, y1, x2, y2) - if edge.directed then - local cx = math.lerp(x1, x2, 0.5) - local cy = math.lerp(y1, y2, 0.5) + local cx = math.lerp(x1, x2, 0.5) + local cy = math.lerp(y1, y2, 0.5) + local arrowSize = 22 + if edge.directed then local alpha = math.atan2(x2 - x1, y2 - y1) - local arrowSize = 15 local triangle = { cx + arrowSize * math.sin(alpha + 0 * math.pi / 3), cy + arrowSize * math.cos(alpha + 0 * math.pi / 3), cx + arrowSize * math.sin(alpha + 2 * math.pi / 3), cy + arrowSize * math.cos(alpha + 2 * math.pi / 3), @@ -124,14 +188,37 @@ function drawGraph(graph) } love.graphics.polygon("fill", triangle) + else + love.graphics.rectangle("fill", cx - arrowSize * .6, cy - arrowSize * .6, arrowSize * 1.2, arrowSize * 1.2) end + love.graphics.setColor(1, 1, 1) + love.graphics.printf(tostring(edge.weight), cx - 20, cy - 10, 40, "center") end for _, node in pairs(nodes) do - love.graphics.setColor(0, 0, 0) - love.graphics.circle("fill", node.x, node.y, 20) + if node.id == selectedNode then + love.graphics.setColor(0, 0.9, 0) + else + love.graphics.setColor(0, 0, 0) + end + love.graphics.circle("fill", node.x, node.y, NODE_OUTER_RADIUS) love.graphics.setColor(255, 255, 255) - love.graphics.circle("fill", node.x, node.y, 17) + love.graphics.circle("fill", node.x, node.y, NODE_INNER_RADIUS) + end +end + +function drawDijkstras(graph, dijkstras) + love.graphics.setFont(GRAPH_FONT) + + for _, node in ipairs(dijkstras) do + if node.distance >= 0 then + local x, y = graph:getNodePos(node.id) + love.graphics.setColor(0, 1, 0) + love.graphics.circle("fill", x, y, NODE_INNER_RADIUS) + + love.graphics.setColor(0, 0, 0) + love.graphics.printf(tostring(node.distance), x - 20, y - 10, 40, "center") + end end end diff --git a/modules/graph_algorithms.c b/modules/graph_algorithms.c index 7b4ed49..fc5aa7e 100644 --- a/modules/graph_algorithms.c +++ b/modules/graph_algorithms.c @@ -61,6 +61,8 @@ int dijkstras(lua_State *L) insert_dj(shortest_distance, distance_walker->node_id, -1); distance_walker = distance_walker->next; } + int last_from; + int last_to; while (connected_nodes != NULL && current_iterations <= iterations) { @@ -93,7 +95,8 @@ int dijkstras(lua_State *L) } visited_tmp = visited_tmp->next; } - + last_to = to; + last_from = from; if (is_in_list(connected_nodes,to) == 1) { @@ -128,7 +131,7 @@ int dijkstras(lua_State *L) lua_newtable(L); lua_pushnumber(L, sdwalker->node_id); - lua_setfield(L, 3, "node_id"); + lua_setfield(L, 3, "id"); lua_pushnumber(L, sdwalker->distance); lua_setfield(L, 3, "distance"); -- 2.25.1