Пример #1
0
                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);
                }
Пример #2
0
        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);
            }
        }
Пример #3
0
 /// <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));
 }
Пример #4
0
 /// <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));
 }
Пример #5
0
                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);
                    }
                }
Пример #6
0
        /// <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));
        }
Пример #7
0
 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);
 }
Пример #8
0
 public VertexEdgePath Rebuild(Topology.Vertex source, Topology.Vertex target)
 {
     Rebuild(source.topology, source.index, target.index);
     return(this);
 }
Пример #9
0
 public bool Remove(Topology.Vertex item)
 {
     throw new NotSupportedException();
 }
Пример #10
0
 public void Insert(int index, Topology.Vertex item)
 {
     throw new NotSupportedException();
 }
Пример #11
0
 public void Add(Topology.Vertex item)
 {
     throw new NotSupportedException();
 }
Пример #12
0
 public bool Contains(Topology.Vertex item)
 {
     return(IndexOf(item) != -1);
 }
Пример #13
0
		/// <inheritdoc/>
		public abstract T this[Topology.Vertex v] { get; set; }
Пример #14
0
		/// <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; }
		}
Пример #15
0
		/// <inheritdoc/>
		public override T this[Topology.Vertex v]
		{
			get { return constant; }
			set { throw new NotSupportedException("Values of a constant vertex attribute cannot be changed."); }
		}
Пример #16
0
 /// <inheritdoc/>
 public IntVector2 GetVertexIndex2D(Topology.Vertex vertex)
 {
     return(GetVertexIndex2D(vertex.index));
 }