how I learned to stop worrying and optimize my Force Directed Graphs







graph,
WHO ARE YOU?






or














fun facts



CW
CCW
'winding'



non orientable manifold, lol!
fun fact
funny properties







funny things to do

Half-Edge
Dijkstra, A*...
Minimum Spanning Tree
normal unifomisation
Delaunay, Voronoi, "navmeshes"
2D visibility


funny things to do
wow, such ALIVE!



GRAPH !
dead penguin ->
funny Force Directed Graph















a funny algorithm
// define the rest length
const restLength = 50;
// update loop
graph.vertices.forEach(function (a) {
//attraction
a.neighbours.forEach(function (b) {
const dx = b.x - a.x;
const dy = b.y - a.y;
const d = Math.sqrt(dx * dx + dy * dy);
const diff = restLength / a.neighbours.length - d;
const offx = ((diff * dx) / d) * 0.5;
const offy = ((diff * dy) / d) * 0.5;
a.x -= offx;
a.y -= offy;
b.x += offx;
b.y += offy;
});
//repulsion
graph.vertices.forEach(function (b) {
if (a == b) return;
const dx = b.x - a.x;
const dy = b.y - a.y;
const d = Math.sqrt(dx * dx + dy * dy);
const diff = restLength - d;
const offx = ((diff * dx) / d) * 0.01;
const offy = ((diff * dy) / d) * 0.01;
a.x -= offx;
a.y -= offy;
b.x += offx;
b.y += offy;
});
});


attract

repel
R: desired edge length


a funny example



funny libs


3D Force-Directed Graph


a funny sample

import ForceGraph3D from "3d-force-graph";
//1 create a FDG simulation
const FDG = ForceGraph3D({
logarithmicDepthBuffer: true, // three.js renderer settings
})(this.container); //<- add renderer to DOM
const data = {nodes:[], links:[]};//get the data from a graph
graph.nodes.forEach((node) => {//create the nodes
data.nodes.push({ x: node.x, y: node.y, z: node.z,
data:'whatever you want this node to hold' });
});
graph.edges.forEach((link) => { //create the edges
data.links.push({ source: link[0], target: link[1], });
});
FDG.graphData(data);//feed the graph data to the FDG

funny helpers
//set some useful helper
FDG.onNodeHover((node) => {}); //get node on roll over
FDG.onNodeClick((node) => {}); //get node on click
FDG.onLinkHover((link) => {}); // same for links
FDG.onLinkClick((link) => {});
FDG.nodeHoverPrecision(10); //click & hover precision (in pixels)
FDG.linkHoverPrecision(10);
//for DAG (Directed Acyclic Graph) only: render presets
FDG.dagLevelDistance(100);
FDG.dagMode("tr");
FDG.warmupTicks(50); //precomputes the layout for X iterations
FDG.cooldownTicks(100); //ticks before calling "onEngineStop"
FDG.onEngineTick(() => {}); //on FDG update
FDG.onEngineStop(() => {}); //called when the FDG has cooled down

funny optimisation
edge = { a : G.nodes[x], b : G.nodes[y] }
G.edges = [ edge, ... ]
ahah silly!

cunning!
G.edges = [ [x, y], [y, z], ... ]
=> G.edges = [ x,y,y,z... ]


funny optimisation








cunning!

funny further reading
all manners of graphs, from theory to practice to actually useful stuffs for game dev and more
PARAGRAPHL
https://nblintao.github.io/ParaGraphL/
(shameless plug) Graph, a hidden hero
https://barradeau.com/blog/?p=651



funny Machine Learning take on graphs encoding
funny Machine Learning take on graphs encoding



"half edge data structure | unreal"
"a graph is a data strcuture | vray"
THAT'S ALL FOLKS!
american pie graph
By nicolas barradeau
american pie graph
- 898