mirror of
https://github.com/rm-code/Graphoon.git
synced 2024-11-16 18:24:22 +00:00
Merge branch 'release/1.0.1'
This commit is contained in:
commit
f5e87bf366
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 = [[
|
||||||
|
27
README.md
27
README.md
@ -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') )
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user