protected void UpdateEdges() { sceneComponents.AcceptEdge(edgeComponent => { AbstractGraphEdge edge = edgeComponent.GetGraphEdge(); AbstractGraphNode startNode = edge.GetStartGraphNode(); AbstractGraphNode endNode = edge.GetEndGraphNode(); sceneComponents.GetNodeComponent(startNode.GetId()).ConnectedRb.Add(sceneComponents.GetNodeComponent(endNode.GetId()).Rb); sceneComponents.GetNodeComponent(endNode.GetId()).ConnectedRb.Add(sceneComponents.GetNodeComponent(startNode.GetId()).Rb); edgeComponent.UpdateGeometry( sceneComponents.GetNodeComponent(startNode.GetId()).GetVisualComponent().transform.position, sceneComponents.GetNodeComponent(endNode.GetId()).GetVisualComponent().transform.position); }); float MostEdgesNodeCount = 0; foreach (var n in sceneComponents.nodeComponents) { if (n.ConnectedRb.Count > MostEdgesNodeCount) { MostEdgesNodeCount = n.ConnectedRb.Count; } } foreach (var n in sceneComponents.nodeComponents) { if (n.ConnectedRb.Count == MostEdgesNodeCount) { n.SetPosition(Vector3.zero); } } }
private void DrawGraphEdge(AbstractGraphEdge edge) { if (graphSceneComponents.HasEdgeComponent(edge)) { return; } EdgeComponent edgeComponent = new EdgeComponent(edge, graphScenePrefabs.InstantiateEdge()); graphSceneComponents.AddEdgeComponent(edgeComponent); NodeComponent startNode = graphSceneComponents.GetNodeComponent(edgeComponent.GetGraphEdge().GetStartGraphNode().GetId()); NodeComponent endNode = graphSceneComponents.GetNodeComponent(edgeComponent.GetGraphEdge().GetEndGraphNode().GetId()); if (endNode == null) { return; } SpringJoint spring = endNode.GetVisualComponent().GetComponent <SpringJoint> (); spring.connectedBody = startNode.GetVisualComponent().GetComponent <Rigidbody> (); // checking if there is any other edge connecting the same nodes long sameNodeConnections = 0; graphSceneComponents.AcceptEdge(existingEdgeComponent => { AbstractGraphEdge existingEdge = existingEdgeComponent.GetGraphEdge(); AbstractGraphNode existingStartNode = existingEdge.GetStartGraphNode(); AbstractGraphNode existingEndNode = existingEdge.GetEndGraphNode(); if ( existingStartNode.GetId() == startNode.GetGraphNode().GetId() && existingEndNode.GetId() == endNode.GetGraphNode().GetId() || existingStartNode.GetId() == endNode.GetGraphNode().GetId() && existingEndNode.GetId() == startNode.GetGraphNode().GetId() ) { sameNodeConnections = sameNodeConnections + 1; } }); if (sameNodeConnections > 1) { edgeComponent.MultiEdge = true; } }
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; }); }
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(); }