Merge branch 'release/1.0.1'

This commit is contained in:
Robert Machmer 2016-01-12 16:11:43 +01:00
commit f5e87bf366
5 changed files with 68 additions and 18 deletions

View File

@ -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 ) ## Version 1.0.0 ( 2016-01-12 )
- Initial Release - Initial Release

View File

@ -36,14 +36,10 @@ function Graph.new()
--- ---
-- Updates the boundaries of the graph. -- Updates the boundaries of the graph.
-- This represents the rectangular area in which all nodes are contained. -- 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 nx - The new x position to check.
-- @param ny - The new y 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 ); 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 end
@ -158,7 +154,7 @@ function Graph.new()
nodeCallback( nodeA ); nodeCallback( nodeA );
end end
minX, maxX, minY, maxY = updateBoundaries( minX, maxX, minY, maxY, nodeA:getPosition() ); minX, maxX, minY, maxY = updateBoundaries( nodeA:getPosition() );
end end
end end

View File

@ -2,14 +2,14 @@ local current = (...):gsub('%.[^%.]+$', '');
local Node = {}; local Node = {};
local FORCE_SPRING = -0.01; local FORCE_SPRING = 0.005;
local FORCE_CHARGE = 100000; local FORCE_CHARGE = 200;
local FORCE_MAX = 4; local FORCE_MAX = 4;
local NODE_SPEED = 8; local NODE_SPEED = 128;
local DAMPING_FACTOR = 0.95; 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 id - A unique id which will be used to reference this node.
@ -17,7 +17,7 @@ local DEFAULT_MASS = 0.05;
-- @param y - The y 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). -- @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 self = {};
local px, py = x or 0, y or 0; local px, py = x or 0, y or 0;
@ -46,17 +46,37 @@ function Node.new( id, x, y, anchor, ... )
ay = clamp( -FORCE_MAX, ay + fy, FORCE_MAX ); ay = clamp( -FORCE_MAX, ay + fy, FORCE_MAX );
end 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. -- Attract this node to another node.
-- @param node - The node to use for force calculation. -- @param node - The node to use for force calculation.
-- --
function self:attractTo( node ) function self:attractTo( node )
local dx, dy = px - node:getX(), py - node:getY(); local dx, dy = getManhattanDistance( node:getPosition() );
local distance = math.sqrt(dx * dx + dy * dy); local distance = getRealDistance( dx, dy );
dx = dx / distance; dx = dx / distance;
dy = dy / distance; dy = dy / distance;
local strength = FORCE_SPRING * distance; local strength = -1 * FORCE_SPRING * distance * 0.5;
applyForce( dx * strength, dy * strength ); applyForce( dx * strength, dy * strength );
end end
@ -65,12 +85,12 @@ function Node.new( id, x, y, anchor, ... )
-- @param node - The node to use for force calculation. -- @param node - The node to use for force calculation.
-- --
function self:repelFrom( node ) function self:repelFrom( node )
local dx, dy = px - node:getX(), py - node:getY(); local dx, dy = getManhattanDistance( node:getPosition() );
local distance = math.sqrt(dx * dx + dy * dy); local distance = getRealDistance( dx, dy );
dx = dx / distance; dx = dx / distance;
dy = dy / 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); applyForce(dx * strength, dy * strength);
end end
@ -119,6 +139,10 @@ function Node.new( id, x, y, anchor, ... )
mass = nmass; mass = nmass;
end end
function self:getMass()
return mass;
end
return self; return self;
end end

View File

@ -1,5 +1,5 @@
return { return {
_VERSION = 'Graphoon v1.0.0', _VERSION = 'Graphoon v1.0.1',
_DESCRIPTION = 'A force directed graph algorithm written in Lua.', _DESCRIPTION = 'A force directed graph algorithm written in Lua.',
_URL = 'https://github.com/rm-code/Graphoon', _URL = 'https://github.com/rm-code/Graphoon',
_LICENSE = [[ _LICENSE = [[

View File

@ -2,6 +2,8 @@
A force directed graph algorithm written in Lua. A force directed graph algorithm written in Lua.
![example](https://cloud.githubusercontent.com/assets/11627131/12252902/a5190d90-b8db-11e5-9199-a9fdb61416ac.png)
## Introduction ## 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). _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).
@ -60,3 +62,28 @@ Or by using the ```setAnchor``` function:
-- Invert anchor status -- Invert anchor status
node:setAnchor( not node:isAnchor(), mouseX, mouseY ) 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') )
```