private void MoveNodes(GraphSceneComponents sceneComponents) { sceneComponents.AcceptNode(v => { SpringLayoutData vd = GetLayoutData(v); vd.xDelta += vd.xRepulsion + vd.x; vd.yDelta += vd.yRepulsion + vd.y; vd.zDelta += vd.zRepulsion + vd.z; v.SetPosition(new Vector3((float)vd.xDelta, (float)vd.yDelta, (float)vd.zDelta)); }); }
private void CalculateRepulsion(GraphSceneComponents sceneComponents) { sceneComponents.AcceptNode(v => { SpringLayoutData layoutData = GetLayoutData(v); double dx = 0; double dy = 0; double dz = 0; sceneComponents.AcceptNode(v2 => { float vx = v.GetPosition().x - v2.GetPosition().x; float vy = v.GetPosition().y - v2.GetPosition().y; float vz = v.GetPosition().z - v2.GetPosition().z; double distanceSq = Mathf.Sqrt(Vector3.Distance(v.GetPosition(), v2.GetPosition())); if (distanceSq == 0) { System.Random random = new System.Random(); dx += random.NextDouble(); dy += random.NextDouble(); dz += random.NextDouble(); } else if (distanceSq < repulsion_range_sq) { float factor = 0.1F; dx += factor * vx / distanceSq; dy += factor * vy / distanceSq; dz += factor * vz / distanceSq; } }); double dlen = dx * dx + dy * dy + dz * dz; if (dlen > 0) { dlen = System.Math.Sqrt(dlen) / 20; layoutData.xRepulsion += dx / dlen; layoutData.yRepulsion += dy / dlen; layoutData.zRepulsion += dz / dlen; } }); }
override protected void UpdateGraphLayout(GraphSceneComponents sceneComponents, float time) { sceneComponents.AcceptNode(nodeComponent => { SpringLayoutData layoutData = GetLayoutData(nodeComponent); layoutData.xDelta /= 4; layoutData.yDelta /= 4; layoutData.zDelta /= 4; layoutData.x = 0; layoutData.y = 0; layoutData.z = 0; layoutData.xRepulsion = 0; layoutData.yRepulsion = 0; layoutData.zRepulsion = 0; }); RelaxEdges(sceneComponents); CalculateRepulsion(sceneComponents); MoveNodes(sceneComponents); UpdateEdges(); }
private void RelaxEdges(GraphSceneComponents sceneComponents) { sceneComponents.AcceptEdge(edgeComponent => { NodeComponent v1 = sceneComponents.GetNodeComponent(edgeComponent.GetGraphEdge().GetStartGraphNode().GetId()); NodeComponent v2 = sceneComponents.GetNodeComponent(edgeComponent.GetGraphEdge().GetEndGraphNode().GetId()); float vx = v1.GetPosition().x - v2.GetPosition().x; float vy = v1.GetPosition().y - v2.GetPosition().y; float vz = v1.GetPosition().z - v2.GetPosition().z; float desiredLen = 5; float len = (float)Mathf.Sqrt(vx * vx + vy * vy + vz * vz); if (len == 0) { len = 1F; } double f = force_multiplier * (desiredLen - len) / len; f = f * Mathf.Pow(stretch, 2); double dx = f * vx; double dy = f * vy; double dz = f * vz; SpringLayoutData v1d = GetLayoutData(v1); SpringLayoutData v2d = GetLayoutData(v2); v1d.x += dx; v1d.y += dy; v1d.z += dz; v2d.x -= dx; v2d.y -= dy; v2d.z -= dz; }); }
public FruchtermanReingoldLayout(GraphSceneComponents sceneComponents) { this.sceneComponents = sceneComponents; }
public SpringLayout(GraphSceneComponents graphSceneComponents) : base(graphSceneComponents) { }
protected override void UpdateGraphLayout(GraphSceneComponents sceneComponents, float time) { float maxDisplace = (float)(Math.Sqrt(AREA_MULTIPLICATOR * area) / 10F); float k = (float)Math.Sqrt(AREA_MULTIPLICATOR * area / (1F + sceneComponents.GetNodesCount())); sceneComponents.AcceptNode(n1 => { sceneComponents.AcceptNode(n2 => { if (n1.GetGraphNode().GetId() != n2.GetGraphNode().GetId()) { float xDist = n1.GetPosition().x - n2.GetPosition().x; float yDist = n1.GetPosition().y - n2.GetPosition().y; float zDist = n1.GetPosition().z - n2.GetPosition().z; float dist = (float)Math.Sqrt(xDist * xDist + yDist * yDist + zDist * zDist); if (dist > 0) { float repulsiveF = k * k / dist; ForceVectorNodeLayoutData layoutData = GetLayoutData(n1); layoutData.dx = xDist / dist * repulsiveF; layoutData.dy = yDist / dist * repulsiveF; layoutData.dz = zDist / dist * repulsiveF; } } }); }); sceneComponents.AcceptEdge(e => { NodeComponent nf = sceneComponents.GetNodeComponent(e.GetGraphEdge().GetStartGraphNode().GetId()); NodeComponent nt = sceneComponents.GetNodeComponent(e.GetGraphEdge().GetEndGraphNode().GetId()); float xDist = nf.GetPosition().x - nt.GetPosition().x; float yDist = nf.GetPosition().y - nt.GetPosition().y; float zDist = nf.GetPosition().z - nt.GetPosition().z; float dist = (float)Math.Sqrt(xDist * xDist + yDist * yDist + zDist * zDist); float attractiveF = dist * dist / k; if (dist > 0) { ForceVectorNodeLayoutData sourceLayoutData = GetLayoutData(nf); ForceVectorNodeLayoutData targetLayoutData = GetLayoutData(nt); sourceLayoutData.dx -= xDist / dist * attractiveF; sourceLayoutData.dy -= yDist / dist * attractiveF; sourceLayoutData.dz -= zDist / dist * attractiveF; targetLayoutData.dx += xDist / dist * attractiveF; targetLayoutData.dy += yDist / dist * attractiveF; targetLayoutData.dz += zDist / dist * attractiveF; } }); sceneComponents.AcceptNode(n => { ForceVectorNodeLayoutData layoutData = GetLayoutData(n); float d = (float)Math.Sqrt(n.GetPosition().x *n.GetPosition().x + n.GetPosition().y *n.GetPosition().y + n.GetPosition().z *n.GetPosition().z); float gf = 0.01F * k * (float)gravity * d; layoutData.dx -= gf * n.GetPosition().x / d; layoutData.dy -= gf * n.GetPosition().y / d; layoutData.dz -= gf * n.GetPosition().z / d; }); // speed sceneComponents.AcceptNode(n => { ForceVectorNodeLayoutData layoutData = GetLayoutData(n); layoutData.dx *= speed / SPEED_DIVISOR; layoutData.dy *= speed / SPEED_DIVISOR; layoutData.dz *= speed / SPEED_DIVISOR; }); sceneComponents.AcceptNode(n => { ForceVectorNodeLayoutData layoutData = GetLayoutData(n); float xDist = layoutData.dx; float yDist = layoutData.dy; float zDist = layoutData.dz; float dist = (float)Math.Sqrt(layoutData.dx * layoutData.dx + layoutData.dy * layoutData.dy + layoutData.dz * layoutData.dz); if (dist > 0) { float limitedDist = Math.Min(maxDisplace * ((float)speed / SPEED_DIVISOR), dist); n.SetPosition(new UnityEngine.Vector3( n.GetPosition().x + xDist / dist * limitedDist, n.GetPosition().y + yDist / dist * limitedDist, n.GetPosition().z + zDist / dist * limitedDist )); } }); UpdateEdges(); }
public FruchtermanReingoldLayout(GraphSceneComponents sceneComponents) : base(sceneComponents) { }