Frustrum GetFrustrum(Vector2 highStart, Vector2 lowStart, NodeEdge nextDoor) { Vector2 lowEnd; Vector2 highEnd; var requiredIndent = DoorWidthRequiredToPassFromPoint(lowStart, nextDoor); //it's ok to calculate just for 1 point with simplified function..for now if (requiredIndent > (nextDoor.P1 - nextDoor.P2).magnitude / 2) { return(null); } if (nextDoor.P1.x == nextDoor.P2.x) { lowEnd = nextDoor.P1.y > nextDoor.P2.y ? nextDoor.P2 + Vector2.up * requiredIndent : nextDoor.P1 + Vector2.up * requiredIndent; highEnd = nextDoor.P1.y > nextDoor.P2.y ? nextDoor.P1 - Vector2.up * requiredIndent : nextDoor.P2 - Vector2.up * requiredIndent; return(new Frustrum { highEnd = highEnd, lowEnd = lowEnd, highStart = highStart, lowStart = lowStart }); } else if (nextDoor.P1.y == nextDoor.P2.y) { lowEnd = nextDoor.P1.x > nextDoor.P2.x ? nextDoor.P2 + Vector2.right * requiredIndent : nextDoor.P1 + Vector2.right * requiredIndent; highEnd = nextDoor.P1.x > nextDoor.P2.x ? nextDoor.P1 - Vector2.right * requiredIndent : nextDoor.P2 - Vector2.right * requiredIndent; return(new Frustrum { highEnd = highEnd, lowEnd = lowEnd, highStart = highStart, lowStart = lowStart }); } else { Debug.LogError("Inconsistent door: " + nextDoor); return(null); } }
private Vector2 ChooseCorner(Vector2 start, NodeEdge nodeEdge, float unitRadius, Vector2 end) { Vector2 corner; var nextNodeEdge = _nodeEdges[_nodeEdges.IndexOf(nodeEdge) + 1]; var middleEdgePoint = new Vector2((nextNodeEdge.P1.x + nextNodeEdge.P2.x) / 2, (nextNodeEdge.P1.y + nextNodeEdge.P2.y) / 2); var firstSectorSide = nodeEdge.P1 + ConstructNormalVector(nodeEdge.P1 - start, unitRadius); var secondSectorSide = nodeEdge.P2 + ConstructNormalVector(nodeEdge.P2 - start, unitRadius); var sectorDot = Vector2.Dot((firstSectorSide - start).normalized, (secondSectorSide - start).normalized); var secondSidePointDot = Vector2.Dot((secondSectorSide - start).normalized, (middleEdgePoint - start).normalized); if (secondSidePointDot < sectorDot) { corner = nodeEdge.P1 + ConstructNormalVector(nodeEdge.P1 - start, unitRadius); } else { corner = nodeEdge.P2 - ConstructNormalVector(nodeEdge.P2 - start, unitRadius); } if (TryFindStraightPathToEnd(corner, end, nodeEdge, unitRadius, out Vector2 betterCorner)) { return(betterCorner); } return(corner); }
/* */ private void RemoveEdgeNode(NodeGraph node, int v) { NodeEdge aux = node.edge; if (aux != null) { if (aux.nodeDestination.nodeValue == v) { node.edge = aux.nextEdge; } else { if (aux.nextEdge != null && aux.nextEdge.nodeDestination.nodeValue != v) { aux = aux.nextEdge; } if (aux.nextEdge != null) { aux.nextEdge = aux.nextEdge.nextEdge; } } } }
private bool BellmanFordIteration() { var hCostsImproved = false; // Für alle Kanten( Für jeden Knoten -> Alle möglichen Kanten des Knotens) // Für jeden vorhandenen Knoten.. foreach (var hCurrentNode in FNodeDictionary.Values) { // Für jede ausgehende Kante.. foreach (var hCurrentNodeEdge in hCurrentNode.NeighbourEdges) { var hNeighborNode = hCurrentNodeEdge.Node; var hEdgeToNeighorNode = hCurrentNodeEdge.Edge; var hCostToNeighbor = FCostDictionary[hCurrentNode] + hEdgeToNeighorNode.GetWeightValue(); // Prüfen ob ich den Nachbarn jetzt günstiger erreichen kann if (hCostToNeighbor < FCostDictionary[hNeighborNode]) { FCostDictionary[hNeighborNode] = hCostToNeighbor; FParentNodeEdge[hNeighborNode] = new NodeEdge(hCurrentNode, hEdgeToNeighorNode); hCostsImproved = true; } } } return(hCostsImproved); }
public Renderer(IForceDirected iForceDirected) : base(iForceDirected) { Transform graphHolder = GameObject.FindWithTag("Graph").transform; GameObject nodePrefab = Resources.Load("Node") as GameObject; GameObject edgePrefab = Resources.Load("Edge") as GameObject; foreach (Node n in iForceDirected.graph.nodes) { //GameObject nodeObj = Instantiate(Resources.Load("Node") as GameObject, new Vector3(n.Data.initialPostion.x, n.Data.initialPostion.y, n.Data.initialPostion.z), Quaternion.identity, graphHolder); GameObject nodeObj = Instantiate(nodePrefab, graphHolder); nodeObj.name = n.Data.label; // Passing the value of the underlying node to the 'Interface' between the GameObject and the actual FDG object var na = nodeObj.GetComponent <NodeAssociation>(); na._associatedNode = n; n.associatedNodeObject = na; n.Data.gameObject = nodeObj; gameObjects.Add(nodeObj); } foreach (Edge e in iForceDirected.graph.edges) { GameObject edgeObj = Instantiate(edgePrefab, graphHolder); edgeObj.name = e.Data.label; NodeEdge nodeEdge = edgeObj.GetComponent <NodeEdge>(); nodeEdge.node1 = e.Source.Data.gameObject; nodeEdge.node2 = e.Target.Data.gameObject; gameObjects.Add(edgeObj); } }
// ---------------------------------------------------------------------- // Returns true if the distance to parent is less then twice the port size. public bool IsNearParentEdge(iCS_EditorObject port, NodeEdge edge = NodeEdge.None) { var parent = port.ParentNode; var pos = port.GlobalPosition; return(parent.IsPositionOnEdge(pos, (edge != NodeEdge.None ? edge : port.Edge))); }
// ---------------------------------------------------------------------- public static bool IsPositionOnRectEdge(Vector2 pos, Rect r, NodeEdge edge) { float maxDistance = iCS_EditorConfig.PortDiameter; float distance = 2f * maxDistance; float leftX = r.xMin; float rightX = r.xMax; float topY = r.yMin; float bottomY = r.yMax; switch (edge) { case NodeEdge.Top: distance = Math3D.DistanceFromHorizontalLineSegment(pos, leftX, rightX, topY); break; case NodeEdge.Bottom: distance = Math3D.DistanceFromHorizontalLineSegment(pos, leftX, rightX, bottomY); break; case NodeEdge.Left: distance = Math3D.DistanceFromVerticalLineSegment(pos, topY, bottomY, leftX); break; case NodeEdge.Right: distance = Math3D.DistanceFromVerticalLineSegment(pos, topY, bottomY, rightX); break; } return(distance <= maxDistance); }
// Create an edge and returns the length private float CreateEdge(Vertex <Node> node1, Vertex <Node> node2) { NodeEdge edge = Instantiate(_NodeEdgePrefab); float length = edge.Init(node1, node2); _edges.Add(edge); _graph.CreateDirectedEdge(node1, node2, length); return(length); }
private bool CanStraightToEnd(Vector3 start, Vector2 end, NodeEdge edge, float unitRadius) { for (int i = _nodeEdges.Count - 1; i >= _nodeEdges.IndexOf(edge); i--) { if (!IsInSector(end, _nodeEdges[i], start, unitRadius)) { return(false); } } return(true); }
/* */ public bool HasEdge(int v1, int v2) { NodeGraph n1 = VertexToNode(v1); NodeEdge aux = n1.edge; if (aux != null && aux.nodeDestination.nodeValue != v2) { aux = aux.nextEdge; } return(aux != null); }
/* */ public int WeightEdge(int v1, int v2) { NodeGraph n1 = VertexToNode(v1); NodeEdge aux = n1.edge; if (aux.nodeDestination.nodeValue != v2) { aux = aux.nextEdge; } return(aux.edgeWeight); }
/* */ public void AddEdge(int id, int v1, int v2, int weight) { NodeGraph n1 = VertexToNode(v1); NodeGraph n2 = VertexToNode(v2); NodeEdge aux = new NodeEdge(); aux.id = id; aux.edgeWeight = weight; aux.nodeDestination = n2; aux.nextEdge = n1.edge; n1.edge = aux; }
public void CreateEdge(IGraphicsCompositorLinkViewModel link) { var sourceVertex = GetVertex(link.SourceSlot.Block); var targetVertex = GetVertex(link.TargetSlot.Block); var nodeEdge = new NodeEdge(sourceVertex, targetVertex) { SourceSlot = link.SourceSlot, TargetSlot = link.TargetSlot }; edgeMapping.Add(link, nodeEdge); linkMapping.Add(nodeEdge, link); edges.Add(nodeEdge); }
float DoorWidthRequiredToPassFromPoint(Vector2 v, NodeEdge door) { float ratio = 1; if (door.P1.y == door.P2.y) { ratio = Mathf.Tan(Mathf.Deg2Rad * Vector2.Angle(Vector2.up, (door.P1 + door.P2) / 2 - v)); } else if (door.P1.x == door.P2.x) { ratio = Mathf.Tan(Mathf.Deg2Rad * Vector2.Angle(Vector2.right, (door.P1 + door.P2) / 2 - v)); } return(radius * Mathf.Abs(ratio) + radius); }
private bool IsInSector(Vector2 start, NodeEdge nodeEdge, Vector2 point, float unitRadius) { var firstSectorSide = nodeEdge.P1 - start + ConstructNormalVector(nodeEdge.P1 - start, unitRadius); var secondSectorSide = nodeEdge.P2 - start + ConstructNormalVector(nodeEdge.P2 - start, unitRadius); var sectorDot = Vector2.Dot((firstSectorSide).normalized, (secondSectorSide).normalized); var firstSidePointDot = Vector2.Dot((firstSectorSide).normalized, (point - start).normalized); var secondSidePointDot = Vector2.Dot((secondSectorSide).normalized, (point - start).normalized); if (firstSidePointDot < sectorDot || secondSidePointDot < sectorDot) { return(false); } return(true); }
public void SetEdges(GraphView view) { Edges = view.edges.ToList().Where(x => { return(x.input.node != null && x.output.node != null); }).Select(x => { var inGuid = x.input.node.viewDataKey; var outGuid = x.output.node.viewDataKey; var edge = new NodeEdge { fromGuid = outGuid, fromPortName = x.output.portName, toGuid = inGuid, toPortName = x.input.portName }; return(edge); }).ToList(); }
private DialogueNode GetNodeAndEdgeNearPoint(Vector2 point) { _resizeEdge = NodeEdge.None; point += _selectedDialogue.EditorScrollPosition; foreach (DialogueNode node in _selectedDialogue.DialogueNodes) { if (Mathf.Abs(node.PositionRect.yMin - point.y) <= _allowedResizeDistance) { if (point.x > node.PositionRect.xMin && point.x < node.PositionRect.xMax) { _resizeEdge = NodeEdge.Top; return(node); } } if (Mathf.Abs(node.PositionRect.xMax - point.x) <= _allowedResizeDistance) { if (point.y > node.PositionRect.yMin && point.y < node.PositionRect.yMax) { _resizeEdge = NodeEdge.Right; return(node); } } if (Mathf.Abs(node.PositionRect.yMax - point.y) <= _allowedResizeDistance) { if (point.x > node.PositionRect.xMin && point.x < node.PositionRect.xMax) { _resizeEdge = NodeEdge.Bottom; return(node); } } if (Mathf.Abs(node.PositionRect.xMin - point.x) <= _allowedResizeDistance) { if (point.y > node.PositionRect.yMin && point.y < node.PositionRect.yMax) { _resizeEdge = NodeEdge.Left; return(node); } } } return(null); }
private bool TryFindStraightPathToEnd(Vector2 corner, Vector2 end, NodeEdge edge, float unitRadius, out Vector2 betterCorner) { betterCorner = Vector2.zero; var minLength = corner.magnitude; float accuracy = unitRadius; corner.Normalize(); for (int i = 0; edge.Node2.Rect.Contains(corner * (minLength + i * accuracy)); i++) { Vector2 nextCorner = corner * (minLength + i * accuracy); if (CanStraightToEnd(nextCorner, end, _nodeEdges[_nodeEdges.IndexOf(edge) + 1], unitRadius)) { betterCorner = nextCorner; return(true); } } return(false); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="args"></param> protected void OnLinkSelected(object sender, LinkSelectedEventArgs args) { // Travel up the visual tree to find the edge FrameworkElement element = args.Link; NodeEdgeControl control = element.FindVisualParentOfType <NodeEdgeControl>(); NodeEdge edge = control.Edge as NodeEdge; Tuple <object, object> link = element.DataContext as Tuple <object, object>; LinkInfo info = selected_links_.FirstOrDefault(x => (x.Link == link) && (x.Edge == edge)); if (info == null) { ClearSelection(); info = new LinkInfo() { Edge = edge, Link = link }; SelectLink(control, info, false); } }
private void Awake() { var n1 = new NodeRect { Rect = new Rect(0, 0, 2, 2) }; var n2 = new NodeRect { Rect = new Rect(1, 2, 2, 2) }; var n3 = new NodeRect { Rect = new Rect(3, 1, 1, 2) }; var n4 = new NodeRect { Rect = new Rect(4, 1, 2, 2) }; _rects = new List <NodeRect> { n1, n2, n3, n4 }; var e1 = new NodeEdge { Node1 = n1, Node2 = n2, P1 = new Vector2(1, 2), P2 = new Vector2(2, 2) }; var e2 = new NodeEdge { Node1 = n2, Node2 = n3, P1 = new Vector2(3, 2), P2 = new Vector2(3, 3) }; var e3 = new NodeEdge { Node1 = n3, Node2 = n4, P1 = new Vector2(4, 1), P2 = new Vector2(4, 3) }; var p1 = new Vector2(0, 0); var p2 = new Vector2(6, 2); _nodeEdges = new List <NodeEdge> { e1, e2, e3 }; _path = CreatePath(p1, p2, _nodeEdges, 0.1f); }
/// <summary> /// Calculate the adjusted walking time for this route, taking congestion into account. /// </summary> /// <param name="allStudentRoutes">A collection of all student routes today.</param> /// <param name="startingTime">The starting time of this route.</param> /// <exception cref="InvalidOperationException"></exception> /// <exception cref="AggregateException"></exception> public void CalculateAdjustedWalkingTime(StudentRoute[] allStudentRoutes, TimeSpan startingTime) { double distanceSoFar = 0; double totalAdjustedWalkingTime = 0; List <Dictionary <(string entryId, string exitId), int> > allCongestionValues = new List <Dictionary <(string entryId, string exitId), int> >(RouteNodes.Count); for (int i = 0; i < RouteNodes.Count - 1; i++) { // Increment the distance walked so far. if (RouteNodes[i].Type == NodeType.Corridor && RouteNodes[i + 1].Type == NodeType.Corridor) { distanceSoFar += RouteNodes[i].DistanceInMetersTo(RouteNodes[i + 1]); } else { distanceSoFar += SharedFunctions.NonCorridorDistance; } // Calculate the time spent getting to this point and get the current time of day from that. TimeSpan currentTime = startingTime.Add(TimeSpan.FromSeconds(SharedFunctions.CalculateWalkingTimeNoRounding(distanceSoFar))); // Calculate the occupancies at this point. Dictionary <(string entryId, string exitId), int> edgeOccupancies = CongestionHelper.CalculateEdgeOccupanciesAtTime(allStudentRoutes, currentTime); if (edgeOccupancies.Count > 0) { // Add to running count for heatmap congestion calculation later. allCongestionValues.Add(edgeOccupancies); } // Get the edge object. NodeEdge edge = RouteNodes[i].OutgoingEdges.Find(e => e.Node2.NodeId == RouteNodes[i + 1].NodeId); if (edge != default) { // Increment the actual walking time. totalAdjustedWalkingTime += Pathfinder.CalculateWalkingTimeWithCongestion(edge, edgeOccupancies).timeWithCongestion; } } // Congestion for heatmap display. Congestion = new Dictionary <string, float>(); if (allCongestionValues.Count > 0) { foreach (Dictionary <(string entryId, string exitId), int> entry in allCongestionValues) { foreach (KeyValuePair <(string entryId, string exitId), int> congestedEdge in entry) { string newKey = $"{congestedEdge.Key.entryId},{congestedEdge.Key.exitId}"; if (!Congestion.TryAdd(newKey, congestedEdge.Value)) { // Already exists, add to it Congestion[newKey] += congestedEdge.Value; } } } if (Congestion.Count > 0) { MaxCongestion = Congestion.Values.Max(); } } WalkingTimeSeconds = Convert.ToInt32(Math.Round(totalAdjustedWalkingTime)); }
// ---------------------------------------------------------------------- public bool IsPortOnNodeEdge(iCS_EditorObject node, NodeEdge edge) { return(IsPortOnRectEdge(node.GlobalRect, edge)); }
private IGraphicsCompositorLinkViewModel GetLink(NodeEdge edge) { return(linkMapping[edge]); }
// ---------------------------------------------------------------------- public bool IsPortOnRectEdge(Rect r, NodeEdge edge) { return(IsPositionOnRectEdge(GlobalPosition, r, edge)); }
/// <summary> /// Verify Node edges on this single floor. /// </summary> /// <param name="nodes">Nodes on this floor</param> /// <param name="edges">Corresponding edges on this floor</param> /// <returns>A list of broken connection errors, if any</returns> public static List <string> VerifyNodeEdgesSingleFloor(List <Node> nodes, List <NodeEdge> edges) { List <string> brokenConnections = new List <string>(); // Iterate through all nodes. foreach (Node node in nodes) { // Ensure this node has connections. NodeEdge[] connections = edges.Where(e => e.Node1Id == node.NodeId || e.Node2Id == node.NodeId).ToArray(); // Iterate through its connections. foreach (NodeEdge connection in connections) { // Skip connections between stairs and lifts because they require more than one floor to verify. if ((connection.Node1Id.StartsWith("s", StringComparison.OrdinalIgnoreCase) && connection.Node2Id.StartsWith("s", StringComparison.OrdinalIgnoreCase)) || (connection.Node1Id.StartsWith("l", StringComparison.OrdinalIgnoreCase) && connection.Node2Id.StartsWith("l", StringComparison.OrdinalIgnoreCase))) { continue; } string node1BC = SharedFunctions.GetBuildingCodeFromId(connection.Node1Id); string node2BC = SharedFunctions.GetBuildingCodeFromId(connection.Node2Id); sbyte node1Floor = -1; try { node1Floor = SharedFunctions.GetLevelFromId(connection.Node1Id); if (node1Floor < 0) { throw new InvalidOperationException("No Level!"); } } catch { brokenConnections.Add($"{connection.Node1Id} is missing a level number in the connection to {connection.Node2Id}"); continue; } sbyte node2Floor = -1; try { node2Floor = SharedFunctions.GetLevelFromId(connection.Node2Id); if (node2Floor < 0) { throw new InvalidOperationException("No Level!"); } } catch { brokenConnections.Add($"{connection.Node2Id} is missing a level number in the connection to {connection.Node1Id}"); continue; } if (string.IsNullOrWhiteSpace(node1BC)) { brokenConnections.Add($"{connection.Node1Id} is missing a building code in its connection to {connection.Node2Id}"); continue; } if (string.IsNullOrWhiteSpace(node2BC)) { brokenConnections.Add($"{connection.Node2Id} is missing a building code in its connection to {connection.Node1Id}"); continue; } // Skip connections between outdoors and indoors - different building, or different floors - codes as they require more than on json file to verify. if (node1BC != node2BC || node1Floor != node2Floor) { continue; } Node node1 = nodes.Find(n => n.NodeId == connection.Node1Id); Node node2 = nodes.Find(n => n.NodeId == connection.Node2Id); // Check both nodes exist. if (node1 == default) { brokenConnections.Add($"Cannot find node: {connection.Node1Id}"); continue; } if (node2 == default) { brokenConnections.Add($"Cannot find node: {connection.Node2Id}"); continue; } NodeEdge result = Array.Find(connections, c => c.Node1Id == node2.NodeId && c.Node2Id == node1.NodeId); // Check a connection exists both ways. if (result == null) { // Connection does not exist. brokenConnections.Add($"Broken Connection: {node1.NodeId} is only connected to {node2.NodeId} one way"); } } } return(brokenConnections); }
public IGraph Execute(INode _StartNode) { var hStopwatch = new Stopwatch(); Console.WriteLine("Start Nearest Neigbor Algorithmus"); hStopwatch.Start(); var hNodeInGraphCount = FUsedGraph.GetNodeDictionary().Count; var hTourCosts = 0.0; var hVisitedNodes = new HashSet <INode>(); var hNearestNeighborGraph = new Graph(); var hCurrentNode = _StartNode; // Auswahl Startknoten. hVisitedNodes.Add(hCurrentNode); hNearestNeighborGraph.CreateNewNode(hCurrentNode.Id); Console.WriteLine("Start bei Knoten ID: " + hCurrentNode.Id); // Solange es noch unbesuchte Knoten gibt while (hVisitedNodes.Count < hNodeInGraphCount) { double hMinimumEdgeWeight = Double.MaxValue; NodeEdge hMinimumNodeEdge = null; // Guck dir alle Nachbarn vom aktuellen Knoten an und wähle die niedrigste Kante zu einem unbesuchten Knoten foreach (var hEdgeToNeighbor in hCurrentNode.NeighbourEdges) { var hEdgeToNeighborWeight = hEdgeToNeighbor.Edge.GetWeightValue(); if (!hVisitedNodes.Contains(hEdgeToNeighbor.Node) && hEdgeToNeighborWeight < hMinimumEdgeWeight) { hMinimumEdgeWeight = hEdgeToNeighborWeight; hMinimumNodeEdge = hEdgeToNeighbor; } } hTourCosts += hMinimumEdgeWeight; hCurrentNode = hMinimumNodeEdge?.Node; hVisitedNodes.Add(hCurrentNode); // Knoten und Kante in neuen Graph einfügen hNearestNeighborGraph.CreateNewNode(hCurrentNode.Id); hNearestNeighborGraph.CreateUndirectedEdge(hMinimumNodeEdge.Edge.GetPossibleEnpoints()[0], hMinimumNodeEdge.Edge.GetPossibleEnpoints()[1], new CostWeighted(hMinimumEdgeWeight)); Console.WriteLine("Zu Knoten-ID: " + hCurrentNode?.Id + "\tKosten: " + hMinimumEdgeWeight); } // Kreis schließen foreach (var hEdgeToNeighbor in hCurrentNode.NeighbourEdges) { if (hEdgeToNeighbor.Node == _StartNode) { hTourCosts += hEdgeToNeighbor.Edge.GetWeightValue(); hNearestNeighborGraph.CreateUndirectedEdge(hEdgeToNeighbor.Edge.GetPossibleEnpoints()[0], hEdgeToNeighbor.Edge.GetPossibleEnpoints()[1], new CostWeighted(hEdgeToNeighbor.Edge.GetWeightValue())); Console.WriteLine("Tour beenden zu ID: " + _StartNode?.Id + "\tKosten: " + hEdgeToNeighbor.Edge.GetWeightValue()); break; } } hStopwatch.Stop(); Console.WriteLine("Gesamtkosten:\t" + hTourCosts); Console.WriteLine("Dauer:\t" + hStopwatch.ElapsedMilliseconds + " ms"); return(hNearestNeighborGraph); }
/// <summary> /// Calculate the congestion multiplier for use in increasing the cost of an edge proportional to the congestion on that edge. /// </summary> /// <param name="edge">Edge to consider.</param> /// <param name="edgeOccupancies">The dictionary of edges and their occupancies at the current time.</param> /// <returns>A decimal multiplier.</returns> public static float CalculateCongestionMultiplier(NodeEdge edge, Dictionary <(string entryId, string exitId), int> edgeOccupancies)
/// <summary> /// Ermittelt den Minimalen Spannbaum mit dem Prim Algorithmus /// </summary> /// <returns>Neuer Graf der den MST repräsentiert</returns> public IGraph Execute() { // Umsetzung des Algorithmus: // hInMst: Liste über alle KnotenIds und speichert ob die jeweilige KnotenId schon im MST drin ist. // hNodeCosts : Liste über KnotenIds und speichert die minimalsten Kosten zu einem Knoten (dient als schneller Vergleich ob es eine günstigere Kante gibt) // hSmallestEdgePq : PriorityQueue, wobei die Priority die Kantenkosten sind und als Value ein NodeEdge Objekt dient FStopwatch.Start(); var hMinimalSpanningTree = new Graph(); double hCosts = 0.0; var hNodeIndex = FUsedGraph.GetNodeDictionary(); var hEdgeIndex = FUsedGraph.GetEdgeIndices(); var hNodesAdded = 0; var hInMst = new List <bool>(); var hNodeCosts = new List <double>(); // Sichert die minimalen Kosten mit denen ein Knoten erreicht werden kann var hSmallestEdgePq = new SimplePriorityQueue <NodeEdge, double>(); // ToDo Bei der Deklaration schon initialisieren for (var i = 0; i < hNodeIndex.Count; i++) { hInMst.Add(false); hNodeCosts.Add(double.MaxValue); } var hStartNodeIndex = 0; var hStartNode = hNodeIndex[hStartNodeIndex]; // ToDo Vorher initialisieren var hStartFakeEdge = new UndirectedEdge(hStartNode, hStartNode, new CostWeighted(0.0)); var hStartNodeEdge = new NodeEdge(hStartNode, hStartFakeEdge); // Fake-Edge für den Startknoten. // Startknoten hinzufügen hSmallestEdgePq.Enqueue(hStartNodeEdge, 0.0); hNodeCosts[hStartNodeIndex] = 0.0; while (hNodesAdded < hNodeIndex.Count) { var hSmallestNodeEdge = hSmallestEdgePq.Dequeue(); var hSmallestEdgesNodeId = hSmallestNodeEdge.Node.Id; if (hInMst[hSmallestEdgesNodeId]) { continue; // Der Zielknoten der kleinsten Kante wurde bereits besucht. Also nächste Iteration durchlaufen (=nächste Kante nehmen) } hInMst[hSmallestEdgesNodeId] = true; hNodesAdded++; // Create MST Graph var hNewNode = new Node(hSmallestEdgesNodeId); hMinimalSpanningTree.CreateNewNode(hSmallestEdgesNodeId); var hFromNodeId = hSmallestNodeEdge.Edge.GetOtherEndpoint(hSmallestNodeEdge.Node).Id; var hFromNode = hMinimalSpanningTree.GetNodeById(hFromNodeId); hMinimalSpanningTree.CreateUndirectedEdge(hNewNode, hFromNode, new CostWeighted(hSmallestNodeEdge.Edge.GetWeightValue())); hCosts += hSmallestNodeEdge.Edge.GetWeightValue(); foreach (var hNeighbourNodeEdges in hSmallestNodeEdge.Node.NeighbourEdges) { var hNeighbourId = hNeighbourNodeEdges.Node.Id; var hNeighbourWeight = hNeighbourNodeEdges.Edge.GetWeightValue(); if (hInMst[hNeighbourId] == false && hNodeCosts[hNeighbourId] > hNeighbourWeight) { hNodeCosts[hNeighbourId] = hNeighbourWeight; hSmallestEdgePq.Enqueue(hNeighbourNodeEdges, hNeighbourWeight); } } } // Die Fake-Edge des Startknotens wieder aus dem MST-Graf rausnehmen. (Es ist die erste Kante des Startknotens) hMinimalSpanningTree.RemoveEdge(hMinimalSpanningTree.GetNodeDictionary()[hStartNodeIndex].NeighbourEdges[0].Edge); FStopwatch.Stop(); Console.WriteLine("--- Prim ---"); Console.WriteLine("Prim-Zeit:\t" + FStopwatch.ElapsedMilliseconds.ToString() + " ms"); Console.WriteLine("Prim-Kosten:\t " + hCosts.ToString()); return(hMinimalSpanningTree); }
// ---------------------------------------------------------------------- // Updates the port edge information from the port type. public void UpdatePortEdge(Vector2 localPosition) { Edge = GetClosestEdge(localPosition); }
private Frustrum FrustrumHitsDoor(Frustrum frustrum, NodeEdge nextDoor) { if (frustrum == null) { return(null); } float highAngle = Vector2.SignedAngle(Vector2.up, frustrum.highEnd - frustrum.highStart); float lowAngle = Vector2.SignedAngle(Vector2.up, frustrum.lowEnd - frustrum.lowStart); Vector2 lowEnd; Vector2 highEnd; var nextFrustrum = GetFrustrum(frustrum.highStart, frustrum.lowStart, nextDoor); if (nextFrustrum == null) { return(null); } if (Vector2.SignedAngle(Vector2.up, nextFrustrum.lowEnd - frustrum.lowEnd) > Vector2.SignedAngle(Vector2.up, nextFrustrum.highEnd - frustrum.highEnd)) { lowEnd = nextFrustrum.highEnd; highEnd = nextFrustrum.lowEnd; } else { highEnd = nextFrustrum.highEnd; lowEnd = nextFrustrum.lowEnd; } float highAngleNext = Vector2.SignedAngle(Vector2.up, highEnd - frustrum.highStart); float lowAngleNext = Vector2.SignedAngle(Vector2.up, lowEnd - frustrum.lowStart);; bool hits = (highAngleNext >= lowAngle && highAngleNext <= highAngle) || (lowAngleNext >= lowAngle && lowAngleNext <= highAngle) || (highAngleNext >= highAngle && lowAngleNext <= lowAngle); Vector2 lowEndNew = lowEnd; Vector2 highEndNew = highEnd; if (highAngleNext < lowAngle || lowAngleNext > highAngle) { return(null); } if (highAngleNext >= lowAngle && highAngleNext <= highAngle) { frustrum.highEnd = GetFrustrum(frustrum.highStart, frustrum.lowStart, nextDoor).highEnd; } else { frustrum.highEnd = highEnd; } if (lowAngleNext >= lowAngle && lowAngleNext <= highAngle) { frustrum.lowEnd = GetFrustrum(frustrum.highStart, frustrum.lowStart, nextDoor).lowEnd; } else { frustrum.lowEnd = lowEnd; } return(frustrum); }