/// <summary>
 /// Initializes a new instance of the <see cref="AgentCellDestination"/> class.
 /// </summary>
 /// <param name="cellDestination">The cell destination.</param>
 public AgentCellDestination(CellDestination cellDestination)
 {
     this.DesirabilityCost = cellDestination.DesirabilityCost;
     //this.NormalizedDirection = cellDestination.NormalizedDirection;
     this.Destination = cellDestination.CellValue;
 }
        // step 4
        /// <summary>
        /// Extracts the escape route.
        /// </summary>
        /// <param name="vantageCell">The vantage cell.</param>
        /// <param name="angleIntercept">The angle intercept.</param>
        /// <param name="collection">The collection.</param>
        /// <param name="staticCosts">The static costs.</param>
        /// <returns>AgentCellDestination[].</returns>
        public static AgentCellDestination[] ExtractedEscapeRoute(Cell vantageCell, int angleIntercept, ICollection <Cell> collection, Dictionary <Cell, double> staticCosts)
        {
            CellDestination[] destinations = new CellDestination[collection.Count];
            int i = 0;

            foreach (var item in collection)
            {
                destinations[i] = new CellDestination(vantageCell, item, staticCosts[item]);
                i++;
            }
            Array.Sort(destinations, new CellDestinationComparerAngleThenCost(angleIntercept));
            //HashSet<CellDestination> SimplifiedSet = new HashSet<CellDestination>(destinations, new CellDestinationComparerAngleOnly(angleIntercept));

            List <CellDestination> simplified = new List <CellDestination> {
                destinations[0]
            };
            CellDestination last  = destinations[0];
            double          angle = (2 * Math.PI) / angleIntercept;

            for (i = 1; i < destinations.Length; i++)
            {
                int a1 = (int)(last.Angle / angle);
                int a2 = (int)(destinations[i].Angle / angle);
                if (a1 != a2)
                {
                    simplified.Add(destinations[i]);
                    last = destinations[i];
                }
            }

            /*
             * */
            bool[] keep = new bool[simplified.Count];
            for (i = 0; i < keep.Length; i++)
            {
                keep[i] = true;
            }
            for (i = 0; i < simplified.Count; i++)
            {
                if (keep[i])
                {
                    int    next_Index = (i < simplified.Count - 1) ? i + 1 : 0;
                    double angleWith_next;

                    if (i < simplified.Count - 1)
                    {
                        angleWith_next = simplified[i + 1].Angle - simplified[i].Angle;
                    }
                    else
                    {
                        angleWith_next = 2 * Math.PI - simplified[i].Angle + simplified[0].Angle;
                    }
                    if (angleWith_next < angle)
                    {
                        if (simplified[i].DesirabilityCost > simplified[next_Index].DesirabilityCost)
                        {
                            keep[i] = false;
                        }
                        else
                        {
                            keep[next_Index] = false;
                        }
                    }
                    if (keep[i])
                    {
                        int    before_Index = (i > 0) ? i - 1 : simplified.Count - 1;
                        double angleWith_Before;
                        if (i > 0)
                        {
                            angleWith_Before = simplified[i].Angle - simplified[i - 1].Angle;
                        }
                        else
                        {
                            angleWith_Before = 2 * Math.PI - simplified[simplified.Count - 1].Angle + simplified[0].Angle;
                        }
                        if (angleWith_Before < angle)
                        {
                            if (simplified[i].DesirabilityCost > simplified[before_Index].DesirabilityCost)
                            {
                                keep[i] = false;
                            }
                            else
                            {
                                keep[before_Index] = false;
                            }
                        }
                    }
                }
            }
            if (keep.Length == 1)
            {
                keep[0] = true;
            }
            List <CellDestination> purged = new List <CellDestination>();

            for (i = 0; i < keep.Length; i++)
            {
                if (keep[i])
                {
                    purged.Add(simplified[i]);
                }
            }
            AgentCellDestination[] isovistCellDestination = new AgentCellDestination[purged.Count];
            for (i = 0; i < purged.Count; i++)
            {
                isovistCellDestination[i] = new AgentCellDestination(purged[i]);
            }
            purged.Clear();
            purged       = null;
            destinations = null;
            simplified.Clear();
            simplified = null;
            keep       = null;

            /*
             * AgentCellDestination[] isovistCellDestination = new AgentCellDestination[simplified.Count];
             * int count = 0;
             * foreach (var item in simplified)
             * {
             *  isovistCellDestination[count] = new AgentCellDestination(item);
             *  count++;
             * }
             */
            return(isovistCellDestination);
        }
Exemplo n.º 3
0
        // SimplifiedEscapeRoute step 2
        /// <summary>
        /// Splits the extracted escape route to a collection of cells which are visible destinations.
        /// </summary>
        /// <param name="vantageCell">The vantage cell.</param>
        /// <param name="angleIntercept">The angle intercept.</param>
        /// <param name="collection">The collection of visible cells at the boundary of the isovist.</param>
        /// <param name="staticCosts">The static costs.</param>
        /// <returns>CellDestination[].</returns>
        public static CellDestination[] SplitExtractedEscapeRoute(Cell vantageCell, int angleIntercept, ICollection <Cell> collection, Dictionary <Cell, double> staticCosts)
        {
            CellDestination[] destinations = new CellDestination[collection.Count];
            var timer = new System.Diagnostics.Stopwatch();
            int i     = 0;

            timer.Start();
            foreach (var item in collection)
            {
                destinations[i] = new CellDestination(vantageCell, item, staticCosts[item]);
                i++;
            }
            Array.Sort(destinations, new CellDestinationComparerAngleThenCost(angleIntercept));
            //HashSet<CellDestination> SimplifiedSet = new HashSet<CellDestination>(destinations, new CellDestinationComparerAngleOnly(angleIntercept));
            //SimplifiedSet.UnionWith(destinations);
            List <CellDestination> simplified = new List <CellDestination> {
                destinations[0]
            };
            CellDestination last  = destinations[0];
            double          angle = (2 * Math.PI) / angleIntercept;

            for (i = 1; i < destinations.Length; i++)
            {
                int a1 = (int)(last.Angle / angle);
                int a2 = (int)(destinations[i].Angle / angle);
                if (a1 != a2)
                {
                    simplified.Add(destinations[i]);
                    last = destinations[i];
                }
            }
            List <CellDestination> purged = new List <CellDestination>();

            bool[] keep = new bool[simplified.Count];
            for (i = 0; i < keep.Length; i++)
            {
                keep[i] = true;
            }
            for (i = 0; i < simplified.Count; i++)
            {
                if (keep[i])
                {
                    int    next_Index = (i < simplified.Count - 1) ? i + 1 : 0;
                    double angleWith_next;

                    if (i < simplified.Count - 1)
                    {
                        angleWith_next = simplified[i + 1].Angle - simplified[i].Angle;
                    }
                    else
                    {
                        angleWith_next = 2 * Math.PI - simplified[i].Angle + simplified[0].Angle;
                    }
                    if (angleWith_next < angle)
                    {
                        if (simplified[i].DesirabilityCost > simplified[next_Index].DesirabilityCost)
                        {
                            keep[i] = false;
                        }
                        else
                        {
                            keep[next_Index] = false;
                        }
                    }
                    if (keep[i])
                    {
                        int    before_Index = (i > 0) ? i - 1 : simplified.Count - 1;
                        double angleWith_Before;
                        if (i > 0)
                        {
                            angleWith_Before = simplified[i].Angle - simplified[i - 1].Angle;
                        }
                        else
                        {
                            angleWith_Before = 2 * Math.PI - simplified[simplified.Count - 1].Angle + simplified[0].Angle;
                        }
                        if (angleWith_Before < angle)
                        {
                            if (simplified[i].DesirabilityCost > simplified[before_Index].DesirabilityCost)
                            {
                                keep[i] = false;
                            }
                            else
                            {
                                keep[before_Index] = false;
                            }
                        }
                    }
                }
            }
            for (i = 0; i < keep.Length; i++)
            {
                if (keep[i])
                {
                    purged.Add(simplified[i]);
                }
            }
            timer.Stop();
            int    prgd = destinations.Length - simplified.Count;
            string s    = timer.Elapsed.TotalMilliseconds.ToString();

            MessageBox.Show("Time: " + s
                            + "\n\t" + simplified.Count.ToString() + " included"
                            + "\n\t" + prgd.ToString() + " removed"
                            + "\n\t" + (simplified.Count - purged.Count).ToString() + "close points removed"
                            + "\n\tMinimum Angle: " + (destinations[0].Angle * 180 / Math.PI).ToString()
                            + "\n\tMaximum Angle: " + (destinations[destinations.Length - 1].Angle * 180 / Math.PI).ToString());
            return(purged.ToArray());
            //return SimplifiedSet.ToArray();
        }