better drawing
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 23 Feb 2019 22:25:48 +0000 (16:25 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 23 Feb 2019 22:25:48 +0000 (16:25 -0600)
lua/graph.lua
lua/regions.lua
main.lua
modules/graph_algorithms.c

index 36c2c3e7ddea753a7b364b59943c936c75ddcd08..7806791835476a4aca8e7d3272b37643821125e2 100644 (file)
@@ -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
index f64cbcce291b3ce145f26d497fc783ddb88c7cda..204e6b004fbc39725a8ca6a436b66fde94423294 100644 (file)
@@ -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]
index dfe843ac1a1f66bdadcd35e5eff2cde0e2494343..a4496037a0751f9c8623b926d062cfc5c7ff8e9c 100644 (file)
--- 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
 
index 7b4ed491e184f1c5c9aa17baa75fe873e3f571f6..fc5aa7e0595eba69486a7d8aa433c5fd483bb498 100644 (file)
@@ -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");