Esempio n. 1
0
        /// <summary>
        /// Get the item in the cell at the specified location
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="map"></param>
        /// <param name="location">A point vector which lies within the cell to be retrieved.</param>
        /// <returns></returns>
        public static T CellAt <T>(this ICellMap <T> map, Vector location)
        {
            int i = map.IndexAt(location);

            if (map.Exists(i))
            {
                return(map[i]);
            }
            else
            {
                return(default(T));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Get the items in the cells at the specified locations
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="map"></param>
        /// <param name="locations"></param>
        /// <returns></returns>
        public static IList <T> CellsAt <T>(this ICellMap <T> map, IList <Vector> locations)
        {
            var result = new List <T>(locations.Count);

            foreach (Vector location in locations)
            {
                int i = map.IndexAt(location);
                if (map.Exists(i))
                {
                    result.Add(map[i]);
                }
            }
            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Generate a field of view within this cell map
        /// </summary>
        /// <param name="fromPoint"></param>
        /// <param name="maxRange"></param>
        /// <param name="transparencyCondition"></param>
        /// <param name="outGrid"></param>
        /// <param name="visibleValue">The value to set in the output grid to indicate visibility</param>
        public static void FieldOfView <E, T>(this ICellMap <T> grid, Vector fromPoint, double maxRange, Func <T, bool> transparencyCondition,
                                              ICellMap <E> outGrid, E visibleValue)
        {
            double         tolerance   = 0.00001;
            double         maxRangeSqd = maxRange * maxRange;
            AngleIntervals shadows     = new AngleIntervals();
            IList <int>    cIs         = grid.CellsOrderedByDistance(fromPoint, Math.Ceiling(maxRange));
            int            current     = grid.IndexAt(fromPoint);

            foreach (int index in cIs)
            {
                Vector centroid = grid.CellPosition(index);
                double distSqd  = fromPoint.DistanceToSquared(centroid);
                if (distSqd > maxRangeSqd)
                {
                    return;                        //Shortcut, reached end of range (?)
                }
                T    item   = grid[index];
                bool opaque = !transparencyCondition.Invoke(item);

                if ((opaque || !shadows.IsEmpty) && index != current)
                {
                    double angle = fromPoint.AngleTo(centroid).NormalizeTo2PI();
                    if (!shadows.isInsideRegion(angle, tolerance))
                    {
                        //Is visible:
                        if (!opaque)
                        {
                            outGrid[index] = visibleValue;
                        }
                    }

                    if (opaque)
                    {
                        //Add to shadows:
                        Angle mindA = 0;
                        Angle maxdA = 0;
                        for (int i = 0; i < grid.VertexCount(index); i++)
                        {
                            Vector vertex = grid.CellVertex(index, i);
                            Angle  dA     = (fromPoint.AngleTo(vertex) - angle).Normalize();
                            if (dA < mindA)
                            {
                                mindA = dA;
                            }
                            if (dA > maxdA)
                            {
                                maxdA = dA;
                            }
                        }
                        mindA *= 0.9;
                        maxdA *= 0.9;
                        Angle start = (angle + mindA).NormalizeTo2PI();
                        Angle end   = (angle + maxdA).NormalizeTo2PI();
                        shadows.addRegion(start, end);

                        //Shortcut: end if full:
                        if (shadows.IsFull)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    outGrid[index] = visibleValue;
                }
            }
        }