diff options
Diffstat (limited to 'graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua')
-rw-r--r-- | graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua new file mode 100644 index 0000000000..41edaba358 --- /dev/null +++ b/graphics/pgf/base/tex/generic/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasPosition.lua @@ -0,0 +1,117 @@ +-- Copyright 2014 by Ida Bruhns +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + + +--- This is a subclass of ForceTemplate, which is used to implement forces +-- that work on individual vertices. The forces depend on the canvas position +-- of the vertices. This class is e.~g.~ used for gravitational forces. + +local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate" +local lib = require "pgf.gd.lib" + +local ForceCanvasPosition = lib.class { base_class = ForceTemplate } + +-- Localize math functions +local max = math.max +local sqrt = math.sqrt +local min = math.min + +-- Implementation starts here: + +function ForceCanvasPosition:constructor () + ForceTemplate.constructor(self) + self.p = {} +end + + +-- This force class works on individual vertices and only depends on their +-- current position. Thus the vertex table of the current graph is simply +-- copied to the variable |p|. +-- +-- @param v The vertices of the graph we are trying to find a layout for. + +function ForceCanvasPosition:preprocess(v) + self.p = v +end + + +-- Applying the force to the vertices and adding the effect to the passed net +-- force array +-- +-- @param data The parameters needed to apply the force: The options table, +-- the current time stamp, an array containing the summed up net +-- forces + +function ForceCanvasPosition:applyTo(data) + --localize + local cap = self.force.cap + local fun_u = self.force.fun_u + local net_forces = data.net_forces + local t_max = self.options["maximum time"] + local t_now = data.t_now + local p = self.p + local time_fun = self.force.time_fun + local initial_gravity = self.options["gravity"] + local fw_attributes = self.fw_attributes + + -- evaluate time function + local time_factor = time_fun(t_max, t_now) + if time_factor == 0 then + return + end + + -- Find midpoint of all vertices since they will be attracted to this point + local centroid_x, centroid_y = 0,0 + for _, v in ipairs(p) do + local pos = v.pos + centroid_x = centroid_x + pos.x + centroid_y = centroid_y + pos.y + end + centroid_x = centroid_x/#p + centroid_y = centroid_y/#p + + -- Iterate over the precomputed vertex list + for _, v in ipairs(p) do + -- localize + local p1 = v.pos + + -- apply force function + local factor = fun_u{attributes = fw_attributes, u = v} + + -- calculate distance between vertex and centroid + local x = centroid_x - p1.x + local y = centroid_y - p1.y + + -- calculate effect on x/y + local h = factor * time_factor + x = x * h + y = y * h + + -- cap effect if necessary + if cap then + if x <= 0 then + x = max(-cap, x) + else + x = min(cap, x) + end + if y <= 0 then + y = max(-cap, y) + else + y = min(cap, y) + end + end + + -- add calculated effect to net forces + local c = net_forces[v] + c.x = c.x + x + c.y = c.y + y + end +end + +return ForceCanvasPosition
\ No newline at end of file |