Exemplo n.º 1
0
        /**
         *      Gets the longest line of connected points that contains this point.
         *
         *      @tparam TCell the type of cell of the grid that this algorithm takes.
         *      @tparam TPoint the type of point of the grid that this algorithm takes.
         *      @tparam TBasePoint the base type of the point.
         *
         *      @see GetConnectedRays
         */
        public static IEnumerable <IEnumerable <TPoint> > GetConnectedLines <TCell, TPoint, TBasePoint>(
            IEvenGrid <TCell, TPoint, TBasePoint> grid,
            TPoint point,
            Func <TPoint, TPoint, bool> isNeighborsConnected)

            where TPoint : ISplicedVectorPoint <TPoint, TBasePoint>, IGridPoint <TPoint>
            where TBasePoint : IVectorPoint <TBasePoint>, IGridPoint <TBasePoint>
        {
            var lines = new List <IEnumerable <TPoint> >();

            foreach (var direction in grid.GetPrincipleNeighborDirections())
            {
                var line = new PointList <TPoint>();
                var edge = point;

                //go forwards
                while (grid.Contains(edge) && isNeighborsConnected(point, edge))
                {
                    edge = edge.MoveBy(direction);
                }

                var oppositeDirection = direction.Negate();
                //TPoint oppositeNeighbor = point.MoveBy(direction.Negate());
                edge = edge.MoveBy(oppositeDirection);

                //go backwards
                while (grid.Contains(edge) && isNeighborsConnected(point, edge))
                {
                    line.Add(edge);
                    edge = edge.MoveBy(oppositeDirection);
                }

                if (line.Count > 1)
                {
                    lines.Add(line);
                }
            }

            return(lines);
        }
Exemplo n.º 2
0
        /**
         *      @param cellDimensions size of the cells in world coordinates
         *      @param rectDimensions size of the rectangle in world coodrinates
         *      @param zeroShapeOffset normalized world coordinates of the shape (0, 0, 0) relative to the rectangle bottom left corner
         *      @param polies each item in the list corresponds to a polygon, andd each polygon is a list of vertices in order (each vertice needs to be included only once).
         *      @param offsets offsets in grid coordinates for each poly relative to (0, 0, 0) in the same order as the polies list
         *      @param rectOffsets the offsets in normalised world coordinates for each splice index
         *      @param pointFactory returns a new spliced point with the given coordinates
         *      @param baseMap returns the world coordinate for the given base point
         *      @param rectPointMap maps the rectangular patches with the correct base point (that corresponds to (0, 0, 0) in that rectangle).
         */

        protected PolygonGridMap(
            Vector2 cellDimensions,
            Vector2 rectDimensions,
            Vector2 zeroShapeOffset,
            IEnumerable <IEnumerable <Vector2> > polies,
            IEnumerable <TPoint> offsets,
            IEnumerable <Vector2> rectOffsets,
            Func <int, int, int, TPoint> pointFactory,
            Func <TBasePoint, Vector2> baseMap,
            Func <VectorPoint, TBasePoint> rectPointMap
            ) :
            base(cellDimensions)
        {
            this.rectDimensions  = rectDimensions;
            this.zeroShapeOffset = zeroShapeOffset.HadamardMul(rectDimensions);
            this.polies          = Scale(polies, rectDimensions).Select(e => e.ToList()).ToList();
            this.offsets         = new PointList <TPoint>(offsets);
            this.pointFactory    = pointFactory;
            this.rectOffsets     = Scale(rectOffsets, rectDimensions).ToList();
            this.baseMap         = baseMap;
            this.rectPointMap    = rectPointMap;
        }
Exemplo n.º 3
0
        /**
         *      Find the shortest path between a start and goal node.
         *
         *      @param grid The grid on which the search is performed.
         *
         *      @param start The start node of the path to be found
         *
         *      @param goal The goal node of the path to be found
         *
         *      @param heuristicCostEstimate A function that returns
         *      an heuristic cost of reaching one node from another.
         *      The heuristic cost estimate must always be equal or
         *      less than the actual cost. This is used to make the algorithm
         *      perform well when the search space is big and the actual cost
         *      calculation is expensive. In other cases, you can use the same
         *      function as the cost parameter.
         *
         *      @param cost The actual cost of reaching one node from
         *      another. In many instances, the distance between the cells
         *      is the cost. But cost can also consider other factors such
         *      as danger, reward, travel time, and so on. This parameter
         *      allows you to specify a cost function that takes this into
         *      account. The cost function is only computed for adjacent
         *      nodes.
         *
         *      A common cost metric is the Euclidean metric, which can
         *      be defined as shown below, with PointyHexPoint replaced
         *      with the appropriate point:
         *
         *      @code
         *      public float EuclideanDistance(PointyHexPoint p1 PointyHexPoint p2)
         *      {
         *              return (map[p1] - map[p2]).magnitude;
         *      }
         *      @endcode
         *
         *      @param isAccessible Whether a cell is accessible.
         *
         *      @tparam TCell the type of cell of the grid that this algorithm takes.
         *      @tparam TPoint the type of point of the grid that this algorithm takes.
         *
         *      @returns The list of nodes on the path in order. If no
         *      path is possible, null is returned.
         *
         *      @version1_7
         */
        public static IEnumerable <TPoint> AStar <TCell, TPoint>(
            IGrid <TCell, TPoint> grid,
            TPoint start,
            TPoint goal,
            Func <TPoint, TPoint, float> heuristicCostEstimate,
            Func <TCell, bool> isAccessible,
            Func <TPoint, TPoint, float> cost)

            where TPoint : IGridPoint <TPoint>
        {
            var closedSet = new PointList <TPoint>();

            // The set of tentative nodes to be evaluated
            var openSet = new PointList <TPoint> {
                start
            };

            // The map of navigated nodes.
            var cameFrom = new Dictionary <TPoint, TPoint>(new PointComparer <TPoint>());

            // Cost from start along best known path.
            var gScore = new Dictionary <TPoint, float>(new PointComparer <TPoint>());

            gScore[start] = 0;

            // Estimated total cost from start to goal through y.
            var fScore = new Dictionary <TPoint, float>(new PointComparer <TPoint>());

            fScore[start] = gScore[start] + heuristicCostEstimate(start, goal);

            while (!openSet.IsEmpty())
            {
                var current = FindNodeWithLowestScore(openSet, fScore);

                if (current.Equals(goal))
                {
                    return(ReconstructPath(cameFrom, goal));
                }

                openSet.Remove(current);
                closedSet.Add(current);

                var currentNodeNeighbors = grid.GetNeighbors(current);

                var accessibleNeighbors = from neighbor in currentNodeNeighbors
                                          where isAccessible(grid[neighbor])
                                          select neighbor;

                foreach (var neighbor in accessibleNeighbors)
                {
                    var tentativeGScore = gScore[current] + cost(current, neighbor);

                    if (closedSet.Contains(neighbor))
                    {
                        if (tentativeGScore >= gScore[neighbor])
                        {
                            continue;
                        }
                    }

                    if (!openSet.Contains(neighbor) || tentativeGScore < gScore[neighbor])
                    {
                        cameFrom[neighbor] = current;
                        gScore[neighbor]   = tentativeGScore;
                        fScore[neighbor]   = gScore[neighbor] + heuristicCostEstimate(neighbor, goal);

                        if (!openSet.Contains(neighbor))
                        {
                            openSet.Add(neighbor);
                        }
                    }
                }
            }

            return(null);
        }
Exemplo n.º 4
0
        public static Dictionary <TPoint, int> GetPointsInRangeCost <TCell, TPoint>(
            IGrid <TCell, TPoint> grid,
            TPoint start,
            Func <TCell, bool> isAcessible,
            Func <TPoint, TPoint, int> getCellMoveCost,
            int moveRange)
            where TPoint : IGridPoint <TPoint>
        {
            // Nodes in range
            var closedSet   = new HashSet <TPoint>(new PointComparer <TPoint>());
            var costToReach = new Dictionary <TPoint, int>(new PointComparer <TPoint>());
            var openSet     = new PointList <TPoint> {
                start
            };

            // Cost from start along best known path up to current point
            var costToReachContains = grid.CloneStructure(false);

            costToReach[start] = 0;

            while (!openSet.IsEmpty())
            {
                // Process current node
                var current = FindNodeWithLowestScore(openSet, costToReach);
                openSet.Remove(current);

                closedSet.Add(current);

                //foreach (var neighbor in grid.GetNeighbors(current))
                var neighbors = grid.GetNeighbors(current).ToPointList();

                for (int i = 0; i < neighbors.Count; i++)
                {
                    var neighbor = neighbors[i];

                    if (!closedSet.Contains(neighbor) &&
                        !openSet.Contains(neighbor) &&
                        isAcessible(grid[neighbor]) &&
                        (costToReach[current] + getCellMoveCost(current, neighbor) <= moveRange)
                        )
                    {
                        // Cost of current node + neighbor's move cost
                        int newCost = costToReach[current] + getCellMoveCost(current, neighbor);

                        if (costToReachContains[neighbor])
                        {
                            if (costToReach[neighbor] > newCost)
                            {
                                costToReach[neighbor] = newCost;
                            }
                        }
                        else
                        {
                            costToReach[neighbor]         = newCost;
                            costToReachContains[neighbor] = true;
                        }

                        openSet.Add(neighbor);
                    }
                }
            }

            return(costToReach);
        }