public int IndexOf(Topology.Vertex item) { if (!_vertexEdgePath.isComplete) { return(-1); } var itemIndex = item.index; if (itemIndex == _vertexEdgePath._sourceElementIndex) { return(0); } var length = _vertexEdgePath._length; var edgeIndices = _vertexEdgePath._edgeIndices; var edgeData = _vertexEdgePath._topology.edgeData; for (int i = 0; i < length; ++i) { if (edgeData[edgeIndices[i]].vertex == itemIndex) { return(i + 1); } } return(-1); }
private static void ExportVertexToSVG(System.IO.TextWriter writer, Topology.Vertex vertex, Topology.FaceEdge edge, Func <Vector3, Vector2> flatten, IVertexAttribute <Vector3> vertexPositions, Vector2 transformedVertexDotRadius, string vertexFormat, string vertexIndexFormat, SVGStyle style, string additionalClasses) { var p = flatten(vertexPositions[edge]); writer.WriteLine(vertexFormat, p.x, p.y, transformedVertexDotRadius.x, transformedVertexDotRadius.y, additionalClasses); if (style.showVertexIndices) { writer.WriteLine(vertexIndexFormat, p.x, p.y, vertex.index, additionalClasses); } }
/// <summary> /// Finds the shortest or path from the specified source vertex to the specified target vertex, /// using the A* algorithm and the supplied vertex positions to measure standard Euclidean /// distance between vertices and over vertex edges. /// </summary> /// <param name="source">The source vertex from which the path should start.</param> /// <param name="target">The target vertex that the path should attempt to reach.</param> /// <param name="vertexPositions">The three dimensional positions of each face in the world.</param> /// <param name="path">An optional existing path created by an earlier call to one of the <seealso cref="O:MakeIt.Tile.PathFinder.FindPath"/> functions, which will be overwritten with the new path data.</param> /// <returns>A vertex edge path instance describing the path found from source to target, or an incomplete object if no path was found.</returns> /// <remarks><para>The optional <paramref name="path"/> parameter is useful for reducing allocation activity /// and pressure on the garbage collector. Reusing an existing path object will not require an additional /// allocation to store the path as long as the new path fits inside the capacity already available in the /// existing path.</para></remarks> public IVertexEdgePath FindEuclideanPath(Topology.Vertex source, Topology.Vertex target, IVertexAttribute <Vector3> vertexPositions, IVertexEdgePath path = null) { return(FindPath(source, target, (Topology.Vertex s, Topology.Vertex t, int pathLength) => { return (vertexPositions[s] - vertexPositions[t]).magnitude; }, (Topology.VertexEdge edge, int pathLength) => { return (vertexPositions[edge.nearVertex] - vertexPositions[edge.farVertex]).magnitude; }, path)); }
/// <summary> /// Finds the shortest or path from the specified source vertex to the specified target vertex, /// using the A* algorithm and the supplied vertex positions to measure spherical arc distance /// between vertices and over vertex edges. /// </summary> /// <param name="source">The source vertex from which the path should start.</param> /// <param name="target">The target vertex that the path should attempt to reach.</param> /// <param name="surface">The surface describing the overall shape of the spherical manifold.</param> /// <param name="vertexPositions">The three dimensional positions of each face in the world.</param> /// <param name="path">An optional existing path created by an earlier call to one of the <seealso cref="O:MakeIt.Tile.PathFinder.FindPath"/> functions, which will be overwritten with the new path data.</param> /// <returns>A vertex edge path instance describing the path found from source to target, or an incomplete object if no path was found.</returns> /// <remarks><para>The optional <paramref name="path"/> parameter is useful for reducing allocation activity /// and pressure on the garbage collector. Reusing an existing path object will not require an additional /// allocation to store the path as long as the new path fits inside the capacity already available in the /// existing path.</para></remarks> public IVertexEdgePath FindSphericalEuclideanPath(Topology.Vertex source, Topology.Vertex target, SphericalSurface surface, IVertexAttribute <Vector3> vertexPositions, IVertexEdgePath path = null) { return(FindPath(source, target, (Topology.Vertex s, Topology.Vertex t, int pathLength) => { var sourcePosition = vertexPositions[s]; var targetPosition = vertexPositions[t]; return Geometry.SphericalArcLength(sourcePosition, targetPosition, surface.radius); }, (Topology.VertexEdge edge, int pathLength) => { var sourcePosition = vertexPositions[edge.nearVertex]; var targetPosition = vertexPositions[edge.farVertex]; return Geometry.SphericalArcLength(sourcePosition, targetPosition, surface.radius); }, path)); }
public void CopyTo(Topology.Vertex[] array, int arrayIndex) { if (!_vertexEdgePath.isComplete) { return; } var topology = _vertexEdgePath._topology; array[arrayIndex++] = new Topology.Vertex(topology, _vertexEdgePath._sourceElementIndex); var length = _vertexEdgePath._length; var edgeIndices = _vertexEdgePath._edgeIndices; var edgeData = _vertexEdgePath._topology.edgeData; for (int i = 0; i < length; ++i) { array[arrayIndex++] = new Topology.Vertex(topology, edgeData[edgeIndices[i]].vertex); } }
/// <summary> /// Finds the shortest or otherwise least costly path from the specified source vertex to /// the specified target vertex, using the A* algorithm and the supplied heuristic and cost /// delegates to measure costs between vertices and over vertex edges. /// </summary> /// <param name="source">The source vertex from which the path should start.</param> /// <param name="target">The target vertex that the path should attempt to reach.</param> /// <param name="costHeuristic">Delegate for estimating the cost of the path from the specified source vertex to the specified target vertex.</param> /// <param name="cost">Delegate for determining the actual cost of the path along the specified vertex edge, from its near vertex to its far vertex.</param> /// <param name="path">An optional existing path created by an earlier call to one of the <seealso cref="O:MakeIt.Tile.PathFinder.FindPath"/> functions, which will be overwritten with the new path data.</param> /// <returns>A vertex edge path instance describing the path found from source to target, or an incomplete object if no path was found.</returns> /// <remarks><para>The optional <paramref name="path"/> parameter is useful for reducing allocation activity /// and pressure on the garbage collector. Reusing an existing path object will not require an additional /// allocation to store the path as long as the new path fits inside the capacity already available in the /// existing path.</para></remarks> public IVertexEdgePath FindPath(Topology.Vertex source, Topology.Vertex target, VertexCostHeuristicDelegate costHeuristic, VertexCostDelegate cost, IVertexEdgePath path = null) { if (!source) { throw new ArgumentException("The source vertex must be a valid vertex.", "source"); } if (!target) { throw new ArgumentException("The target vertex must be a valid vertex.", "target"); } if (!source.topology != target.topology) { throw new ArgumentException("The target vertex must belong to the same topology as the source vertex.", "target"); } var concretePath = path as VertexEdgePath; if (concretePath == null) { if (path != null) { throw new ArgumentException("The provided pre-allocated path was not an instance of the necessary underlying type recognized by this path finder.", "path"); } concretePath = new VertexEdgePath(); } var topology = source.topology; if (source == target) { return(concretePath.Rebuild(source, target)); } if (_queue == null) { _queue = new DelegateOrderedPriorityQueue <Node>(Node.AreOrdered, Mathf.CeilToInt(Mathf.Sqrt(source.topology.vertices.Count))); _openSet = new Dictionary <int, Node>(); _closedSet = new Dictionary <int, Node>(); } else { _queue.Clear(); _openSet.Clear(); _closedSet.Clear(); } _queue.Push(new Node(0f, 0f, costHeuristic(source, target, 0), source.index, -1, -1, 0)); _openSet.Add(source.index, _queue.front); while (_queue.Count > 0) { var node = _queue.front; _queue.Pop(); if (node._elementIndex == target.index) { return(concretePath.Rebuild(source, target, node, _closedSet)); } _closedSet.Add(node._elementIndex, node); var vertex = new Topology.Vertex(topology, node._elementIndex); foreach (var edge in vertex.edges) { if (_closedSet.ContainsKey(edge.vertex.index)) { continue; } var g = node._g + cost(edge, node._length); if (!float.IsPositiveInfinity(g)) { Node neighborNode; if (!_openSet.TryGetValue(edge.vertex.index, out neighborNode)) { var h = costHeuristic(edge.vertex, target, node._length); neighborNode = new Node(g + h, g, h, edge.vertex.index, edge.index, node._elementIndex, node._length + 1); _queue.Push(neighborNode); _openSet.Add(edge.vertex.index, neighborNode); } else if (g < neighborNode._g) { var h = costHeuristic(edge.vertex, target, node._length); neighborNode = new Node(g + h, g, h, edge.vertex.index, edge.index, node._elementIndex, node._length + 1); _openSet[edge.vertex.index] = neighborNode; _queue.Reprioritize(neighborNode); } } } } return(concretePath.Rebuild(source, target)); }
public VertexEdgePath Rebuild(Topology.Vertex source, Topology.Vertex target, Node lastNode, Dictionary <int, Node> closedSet) { Rebuild(source.topology, source.index, target.index, lastNode, closedSet); return(this); }
public VertexEdgePath Rebuild(Topology.Vertex source, Topology.Vertex target) { Rebuild(source.topology, source.index, target.index); return(this); }
public bool Remove(Topology.Vertex item) { throw new NotSupportedException(); }
public void Insert(int index, Topology.Vertex item) { throw new NotSupportedException(); }
public void Add(Topology.Vertex item) { throw new NotSupportedException(); }
public bool Contains(Topology.Vertex item) { return(IndexOf(item) != -1); }
/// <inheritdoc/> public abstract T this[Topology.Vertex v] { get; set; }
/// <summary> /// Accesses the vertex attribute value in the array corresponding to the given vertex. /// </summary> /// <param name="v">The vertex whose attribute value is to be accessed.</param> /// <returns>The vertex attribute value corresponding to the given vertex.</returns> public T this[Topology.Vertex v] { get { return array[v.index]; } set { array[v.index] = value; } }
/// <inheritdoc/> public override T this[Topology.Vertex v] { get { return constant; } set { throw new NotSupportedException("Values of a constant vertex attribute cannot be changed."); } }
/// <inheritdoc/> public IntVector2 GetVertexIndex2D(Topology.Vertex vertex) { return(GetVertexIndex2D(vertex.index)); }