/// <summary> /// Adds a new settled vertex. /// </summary> public static uint AddSettledVertex(this PathTree tree, uint vertex, float weight, Dir dir, uint hops, uint pPointer) { var hopsAndDirection = hops * 4 + dir._val; return(tree.Add(vertex, (uint)(weight * WeightFactor), hopsAndDirection, pPointer)); }
/// <summary> /// Adds a new settled vertex. /// </summary> public static uint AddSettledVertex(this PathTree tree, uint vertex, WeightAndDir <float> weightAndDir, uint hops) { var hopsAndDirection = hops * 4 + weightAndDir.Direction._val; return(tree.Add(vertex, (uint)(weightAndDir.Weight * WeightFactor), hopsAndDirection)); }
/// <summary> /// Adds a new settled vertex. /// </summary> public static uint AddSettledVertex(this PathTree tree, uint vertex, float weight, Dir dir, uint hops) { var hopsAndDirection = hops * 4 + dir._val; return(tree.Add(vertex, (uint)(weight * 10), hopsAndDirection)); }
/// <summary> /// Adds a new visit the path tree. /// </summary> /// <param name="tree">The tree.</param> /// <param name="vertex">The vertex.</param> /// <param name="edge">The edge.</param> /// <param name="previousPointer">The pointer to the previous entry.</param> /// <returns>A pointer to the visit.</returns> public static uint AddVisit(this PathTree tree, VertexId vertex, uint edge, uint previousPointer) { var data0 = vertex.TileId; var data1 = vertex.LocalId; var data2 = edge; var data3 = previousPointer; return(tree.Add(data0, data1, data2, data3)); }
/// <summary> /// Adds a vertex to the path tree. /// </summary> public override uint AddPathTree(PathTree tree, uint vertex, float weight, uint previous) { return(tree.Add(vertex, (uint)(weight * 10.0f), previous)); }
/// <summary> /// Finds loops and merges them together. /// </summary> /// <param name="maxSettles">The maximum labels to settle.</param> /// <param name="updateLabel">A callback to update label.</param> internal void FindLoops(uint maxSettles, IslandLabels islandLabels, Action <uint, uint> updateLabel) { // TODO: it's probably better to call reduce here when too much has changed. var pathTree = new PathTree(); var enumerator = _graph.GetEdgeEnumerator(); var settled = new HashSet <uint>(); var queue = new Queue <uint>(); var loop = new HashSet <uint>(); // keeps all with a path back to label, initially only label. uint label = 0; while (label < _graph.VertexCount) { if (!enumerator.MoveTo(label)) { label++; continue; } if (islandLabels[label] != label) { label++; continue; } queue.Clear(); pathTree.Clear(); settled.Clear(); loop.Add(label); queue.Enqueue(pathTree.Add(label, uint.MaxValue)); while (queue.Count > 0 && settled.Count < maxSettles) { var pointer = queue.Dequeue(); pathTree.Get(pointer, out var current, out var previous); if (settled.Contains(current)) { continue; } settled.Add(current); if (!enumerator.MoveTo(current)) { continue; } while (enumerator.MoveNext()) { var n = enumerator.Neighbour; n = islandLabels[n]; if (loop.Contains(n)) { // yay, a loop! loop.Add(current); while (previous != uint.MaxValue) { pathTree.Get(previous, out current, out previous); loop.Add(current); } } if (settled.Contains(n)) { continue; } queue.Enqueue(pathTree.Add(n, pointer)); } } if (loop.Count > 0) { this.Merge(loop, updateLabel); } loop.Clear(); // move to the next label. label++; } }