/// <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); }
// 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(); }