Skip to content

Commit

Permalink
Merge branch 'release/1.0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
rm-code committed Jan 12, 2016
2 parents ee8885a + abfaac9 commit f5e87bf
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
## Version 1.0.1 ( 2016-01-12 )
- Fix [#1](https://github.com/rm-code/Graphoon/issues/1) - Adjusted force calculation and hopefully made it more stable

## Version 1.0.0 ( 2016-01-12 )
- Initial Release
8 changes: 2 additions & 6 deletions Graphoon/Graph.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,10 @@ function Graph.new()
---
-- Updates the boundaries of the graph.
-- This represents the rectangular area in which all nodes are contained.
-- @param minX - The current minimum x position.
-- @param maxX - The current maximum y position.
-- @param minY - The current minimum x position.
-- @param maxY - The current maximum y position.
-- @param nx - The new x position to check.
-- @param ny - The new y position to check.
--
local function updateBoundaries( minX, maxX, minY, maxY, nx, ny )
local function updateBoundaries( nx, ny )
return math.min( minX or nx, nx ), math.max( maxX or nx, nx ), math.min( minY or ny, ny ), math.max( maxY or ny, ny );
end

Expand Down Expand Up @@ -158,7 +154,7 @@ function Graph.new()
nodeCallback( nodeA );
end

minX, maxX, minY, maxY = updateBoundaries( minX, maxX, minY, maxY, nodeA:getPosition() );
minX, maxX, minY, maxY = updateBoundaries( nodeA:getPosition() );
end
end

Expand Down
46 changes: 35 additions & 11 deletions Graphoon/Node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ local current = (...):gsub('%.[^%.]+$', '');

local Node = {};

local FORCE_SPRING = -0.01;
local FORCE_CHARGE = 100000;
local FORCE_SPRING = 0.005;
local FORCE_CHARGE = 200;

local FORCE_MAX = 4;
local NODE_SPEED = 8;
local NODE_SPEED = 128;
local DAMPING_FACTOR = 0.95;

local DEFAULT_MASS = 0.05;
local DEFAULT_MASS = 3;

---
-- @param id - A unique id which will be used to reference this node.
-- @param x - The x coordinate the Node should be spawned at (optional).
-- @param y - The y coordinate the Node should be spawned at (optional).
-- @param anchor - Wether the node should be locked in place or not (optional).
--
function Node.new( id, x, y, anchor, ... )
function Node.new( id, x, y, anchor )
local self = {};

local px, py = x or 0, y or 0;
Expand Down Expand Up @@ -46,17 +46,37 @@ function Node.new( id, x, y, anchor, ... )
ay = clamp( -FORCE_MAX, ay + fy, FORCE_MAX );
end

---
-- Calculates the manhattan distance from the node's coordinates to the
-- target coordinates.
-- @param tx - The target coordinate in x-direction.
-- @param ty - The target coordinate in y-direction.
--
local function getManhattanDistance( tx, ty )
return px - tx, py - ty;
end

---
-- Calculates the actual distance vector between the node's current
-- coordinates and the target coordinates based on the manhattan distance.
-- @param dx - The horizontal distance.
-- @param dy - The vertical distance.
--
local function getRealDistance( dx, dy )
return math.sqrt( dx * dx + dy * dy ) + 0.1;
end

---
-- Attract this node to another node.
-- @param node - The node to use for force calculation.
--
function self:attractTo( node )
local dx, dy = px - node:getX(), py - node:getY();
local distance = math.sqrt(dx * dx + dy * dy);
local dx, dy = getManhattanDistance( node:getPosition() );
local distance = getRealDistance( dx, dy );
dx = dx / distance;
dy = dy / distance;

local strength = FORCE_SPRING * distance;
local strength = -1 * FORCE_SPRING * distance * 0.5;
applyForce( dx * strength, dy * strength );
end

Expand All @@ -65,12 +85,12 @@ function Node.new( id, x, y, anchor, ... )
-- @param node - The node to use for force calculation.
--
function self:repelFrom( node )
local dx, dy = px - node:getX(), py - node:getY();
local distance = math.sqrt(dx * dx + dy * dy);
local dx, dy = getManhattanDistance( node:getPosition() );
local distance = getRealDistance( dx, dy );
dx = dx / distance;
dy = dy / distance;

local strength = FORCE_CHARGE * ( mass / ( distance * distance ));
local strength = FORCE_CHARGE * (( mass * node:getMass() ) / ( distance * distance ));
applyForce(dx * strength, dy * strength);
end

Expand Down Expand Up @@ -119,6 +139,10 @@ function Node.new( id, x, y, anchor, ... )
mass = nmass;
end

function self:getMass()
return mass;
end

return self;
end

Expand Down
2 changes: 1 addition & 1 deletion Graphoon/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
return {
_VERSION = 'Graphoon v1.0.0',
_VERSION = 'Graphoon v1.0.1',
_DESCRIPTION = 'A force directed graph algorithm written in Lua.',
_URL = 'https://github.com/rm-code/Graphoon',
_LICENSE = [[
Expand Down
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

A force directed graph algorithm written in Lua.

![example](https://cloud.githubusercontent.com/assets/11627131/12252902/a5190d90-b8db-11e5-9199-a9fdb61416ac.png)

## Introduction

_Graphoon_ emerged from the graph calculation code used in both [LoGiVi](https://github.com/rm-code/logivi) and [LoFiVi](https://github.com/rm-code/lofivi).
Expand Down Expand Up @@ -60,3 +62,28 @@ Or by using the ```setAnchor``` function:
-- Invert anchor status
node:setAnchor( not node:isAnchor(), mouseX, mouseY )
```

### Using custom classes for Nodes and Edges

If you prefer to not touch the default classes, you can simply inherit from them and tell Graphoon to use your custom classes instead.

```lua
local GraphLibraryNode = require('lib.libfdgraph.fd').Node

local CustomNodeClass = {}

-- You can pass additional arguments to your custom class. Just make sure the
-- default parameters ar in the right order.
function CustomNodeClass.new( id, x, y, anchor, ... )
local self = GraphLibraryNode.new( id, x, y, anchor )

-- ... Custom code
end

return CustomNodeClass
```

```lua
local GraphLibrary = require('Graphoon').Graph
GraphLibrary.setNodeClass( require('CustomNodeClass') )
```

0 comments on commit f5e87bf

Please sign in to comment.