summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua')
-rw-r--r--Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua201
1 files changed, 201 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua
new file mode 100644
index 00000000000..6d9e69745ed
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/jedi/forcetypes/ForceCanvasDistance.lua
@@ -0,0 +1,201 @@
+-- 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 between
+-- vertex pairs. The forces depend on the canvas distance of the vertices in
+-- the pair. This class is e.~g.~ used for electric forces.
+
+-- Imports
+local ForceTemplate = require "pgf.gd.force.jedi.base.ForceTemplate"
+local lib = require "pgf.gd.lib"
+local Preprocessing = require "pgf.gd.force.jedi.base.Preprocessing"
+
+-- Localize math functions
+local max = math.max
+local sqrt = math.sqrt
+local min = math.min
+
+-- Implementation starts here:
+local ForceCanvasDistance = lib.class { base_class = ForceTemplate }
+
+function ForceCanvasDistance:constructor ()
+ ForceTemplate.constructor(self)
+ self.p = {}
+end
+
+
+-- This force class works on all pairwise disjoint vertex pairs. This
+-- function generates a new graph object containing all vertices from the
+-- original graph and arcs between all pairwise disjoint vertex pairs. The
+-- arcs-table of this new object will be saved in the variable |p|.
+--
+-- @param v The vertices of the graph we are trying to find a layout for.
+
+function ForceCanvasDistance:preprocess(v)
+ self.p = Preprocessing.allPairs(v)
+end
+
+
+-- Applying the force to the vertices and adding the effect to the passed net
+-- force array
+--
+-- @param data The parameters needed to aplly the force: The options table,
+-- the current time stamp, an array containing the summed up net
+-- forces
+
+function ForceCanvasDistance:applyTo(data)
+ -- locals for speed
+ local cap = self.force.cap
+ local fun_u = self.force.fun_u
+ local fun_v = self.force.fun_v
+ local net_forces = data.net_forces
+ local t_max = self.options["maximum time"]
+ local t_now = data.t_now
+ local k = data.k
+ local p = self.p
+ local time_fun = self.force.time_fun
+ 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
+
+ if not fun_v then
+ local data = { k = k, attributes = fw_attributes }
+ for _, i in ipairs(p) do
+ -- dereference
+ local p2 = i.head
+ local p1 = i.tail
+ local p2_pos = p2.pos
+ local p1_pos = p1.pos
+
+ -- calculate distance between two points
+ local x = p2_pos.x - p1_pos.x
+ local y = p2_pos.y - p1_pos.y
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- apply force function
+ data.u = p2
+ data.v = p1
+ data.d = d
+ local e = fun_u(data)
+
+ -- Include time function
+ local f = e * time_factor / d
+
+ -- calculate effect on x/y
+ local g = x * f
+ local h = y * f
+
+ -- cap effect if necessary
+ if cap then
+ if g <= 0 then
+ x = max(-cap, g)
+ else
+ x = min(cap, g)
+ end
+
+ if h <= 0 then
+ y = max(-cap, h)
+ else
+ y = min(cap, h)
+ end
+ else
+ x = g
+ y = h
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[p1]
+ c1.x = c1.x - x
+ c1.y = c1.y - y
+ local c2 = net_forces[p2]
+ c2.x = c2.x + x
+ c2.y = c2.y + y
+ end
+ else
+ -- There are different functions for head and tail vertex
+ local data = { k = k, attributes = fw_attributes }
+ for _, i in ipairs(p) do
+ -- dereference
+ local p2 = i.head
+ local p1 = i.tail
+ local p2_pos = p2.pos
+ local p1_pos = p1.pos
+
+ -- calculate distance between two points
+ local x = p2_pos.x - p1_pos.x
+ local y = p2_pos.y - p1_pos.y
+ local d = max(sqrt(x*x+y*y),0.1)
+
+ -- apply force function to distance and k (natural spring length
+ data.u = p2
+ data.v = p1
+ data.d = d
+ local e_head = fun_u(data)
+ local e_tail = fun_v(data)
+
+ -- Include time function
+ local f_head = time_factor * e_head / d
+ local f_tail = time_factor * e_tail / d
+
+ -- calculate effect on x/y
+ local g_head = x * f_head
+ local g_tail = x * f_tail
+ local h_head = y * f_head
+ local h_tail = y * f_tail
+
+ -- cap effect if necessary
+ local x_head, x_tail, y_head, y_tail
+ if cap then
+ if g_head <= 0 then
+ x_head = max(-cap, g_head)
+ else
+ x_head = min(cap, g_head)
+ end
+
+ if g_tail <= 0 then
+ x_tail = max(-cap, g_tail)
+ else
+ x_tail = min(cap, g_tail)
+ end
+
+ if h_head <= 0 then
+ y_head = max(-cap, h_head)
+ else
+ y_head = min(cap, h_head)
+ end
+
+ if h_tail <= 0 then
+ y_tail = max(-cap, h_tail)
+ else
+ y_tail = min(cap, h_tail)
+ end
+ else
+ x_head = g_head
+ x_tail = g_tail
+ y_head = h_head
+ y_tail = h_tail
+ end
+
+ -- add calculated effect to net forces
+ local c1 = net_forces[p1]
+ c1.x = c1.x - x_tail
+ c1.y = c1.y - y_tail
+ local c2 = net_forces[p2]
+ c2.x = c2.x + x_head
+ c2.y = c2.y + y_head
+ end
+ end
+end
+
+return ForceCanvasDistance \ No newline at end of file