/// <summary> /// Gets the intersection of a plane at the specified height as a list of contours (i.e a list of 2D polygons). /// </summary> /// <param name="elevation">The elevation.</param> /// <returns>List<BarrierPolygons>.</returns> public List <BarrierPolygon> GetIntersection(double elevation) { var edges = new List <UVLine>(); foreach (var item in this._faces) { if (item.Intersects(elevation)) { var edge = item.GetIntersection(elevation); UV p1 = new UV(edge.Start.X, edge.Start.Y); UV p2 = new UV(edge.End.X, edge.End.Y); edges.Add(new UVLine(p1, p2)); } } var plines = PLine.ExtractPLines(edges); List <BarrierPolygon> boundary = new List <BarrierPolygon>(); foreach (PLine item in plines) { var oneBoundary = item.Simplify(0.001d, 0.0001d); if (oneBoundary != null) { var polygon = new BarrierPolygon(oneBoundary.ToArray()) { IsClosed = item.Closed }; boundary.Add(polygon); } } return(boundary); }
/// <summary> /// Initializes a new instance of the <see cref="ActivityDestination"/> class. /// </summary> /// <param name="activityDestination">The activity destination to be copied deeply.</param> public ActivityDestination(ActivityDestination activityDestination) { this.EngagedActivityName = activityDestination.Name; this._destinationArea = activityDestination.DestinationArea; this.DefaultState = activityDestination.DefaultState; this._minimumEngagementTime = activityDestination._minimumEngagementTime; this._maximumEngagementTime = activityDestination._maximumEngagementTime; this.Origins = activityDestination.Origins; }
/// <summary> /// Initializes a new instance of the <see cref="ActivityDestination"/> class. /// </summary> /// <param name="name">The name of activity.</param> /// <param name="origins">The origins of the activity.</param> /// <param name="defaultState">The default state of the agent in the activity area.</param> /// <param name="destinationArea">The destination area.</param> public ActivityDestination(string name, HashSet <Cell> origins, StateBase defaultState, BarrierPolygon destinationArea) { this.DefaultState = defaultState; this._destinationArea = destinationArea; //trim the unwanted chars from the input name char[] charsToTrim = { ' ', '\'' }; this.EngagedActivityName = name.Trim(charsToTrim); this.Origins = origins; }
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { this._activity = null; this._trailIndices.Clear(); this._trailIndices = null; this._destination = null; this._defaultState = null; this._cellDestination = null; }
/// <summary> /// creates an Activity Destination from its string representation /// </summary> /// <param name="lines">The lines.</param> /// <param name="startIndex">The start index.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>ActivityDestination.</returns> /// <exception cref="System.ArgumentException"> /// Activity does not include a name! /// or /// Failed to parse activity's engagement duration: " + lines[startIndex + 3] /// or /// Activity does not include cell origins! /// or /// Failed to set activity engagement duration! /// </exception> public static ActivityDestination FromString(List <string> lines, int startIndex, Length_Unit_Types unitType, CellularFloor cellularFloor, double tolerance = 0.0000001d) { string name = lines[startIndex]; if (string.IsNullOrEmpty(lines[startIndex]) || string.IsNullOrWhiteSpace(lines[startIndex])) { throw new ArgumentException("Activity does not include a name!"); } StateBase state = StateBase.FromStringRepresentation(lines[startIndex + 1]); BarrierPolygon barrier = BarrierPolygon.FromStringRepresentation(lines[startIndex + 2]); //unit converion UnitConversion.Transform(state.Location, unitType, cellularFloor.UnitType); UnitConversion.Transform(state.Velocity, unitType, cellularFloor.UnitType); UnitConversion.Transform(barrier.BoundaryPoints, unitType, cellularFloor.UnitType); var strings = lines[startIndex + 3].Split(','); double min = 0, max = 0; if (!double.TryParse(strings[0], out min) || !double.TryParse(strings[1], out max)) { throw new ArgumentException("Failed to parse activity's engagement duration: " + lines[startIndex + 3]); } HashSet <Cell> origins = new HashSet <Cell>(); var indices = cellularFloor.GetIndicesInsideBarrier(barrier, tolerance); if (indices.Count > 0) { foreach (var index in indices) { Cell cell = cellularFloor.FindCell(index); if (cell != null && cell.FieldOverlapState == OverlapState.Inside) { origins.Add(cell); } } } if (origins.Count == 0) { throw new ArgumentException("Activity does not include cell origins!"); } ActivityDestination dest = new ActivityDestination(name, origins, state, barrier); if (!dest.TrySetEngagementTime(min, max)) { throw new ArgumentException("Failed to set activity engagement duration!"); } return(dest); }
/// <summary> /// Returns an array of barriers that is used for autonomous walking scenarios /// </summary> /// <param name="offsetValue">Human body size which is the distance that you want the agents from barriers</param> /// <returns>Expanded version of all barrier polygons including field naked edges and holes, visual barriers and physical barriers </returns> public BarrierPolygon[] ExpandAllBarrierPolygons(double offsetValue) { ClipperOffset clipperOffset = new ClipperOffset(); //clipperOffset.AddPaths(this.FootPrintOfAllBarriers, JoinType.jtSquare, EndType.etClosedPolygon); clipperOffset.AddPaths(this.FootPrintPolygonsOfFieldWithVoids, JoinType.jtSquare, EndType.etClosedPolygon); INTPolygons plygns = new INTPolygons(); double uniqueOffsetValue = -Math.Pow(10.0, this.PolygonalBooleanPrecision) * offsetValue; clipperOffset.Execute(ref plygns, uniqueOffsetValue); List <BarrierPolygon> brrs = new List <BarrierPolygon>(); for (int i = 0; i < plygns.Count; i++) { BarrierPolygon brr = this.ConvertINTPolygonToBarrierPolygon(plygns[i]); if (brr.Length > 0) { brrs.Add(brr); } } clipperOffset.Clear(); plygns.Clear(); return(brrs.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="Activity"/> class. /// </summary> /// <param name="potentials">The potentials.</param> /// <param name="origins">The origins.</param> /// <param name="destinationArea">The destination area.</param> /// <param name="defaultState">The default state.</param> /// <param name="engagedActivityName">Name of the engaged activity.</param> /// <param name="cellularFloor">The cellular floor.</param> public Activity(Dictionary <Cell, double> potentials, HashSet <Cell> origins, BarrierPolygon destinationArea, StateBase defaultState, string engagedActivityName, CellularFloor cellularFloor) : base(engagedActivityName, origins, defaultState, destinationArea) { this.Potentials = potentials; this.EngagedActivityName = engagedActivityName; this._cellularFloor = cellularFloor; this._min = double.PositiveInfinity; this._max = double.NegativeInfinity; foreach (var item in this.Potentials.Values) { this._max = (this._max < item) ? item : this._max; this._min = (this._min > item) ? item : this._min; } this.Origins = new HashSet <Cell>(origins); this.DefaultState = defaultState.Copy(); //this._destinationArea = destinationArea; this.UseToCaptureEvent = true; }
private void mouseLeftButtonDown_GetProxemics(object sender, MouseButtonEventArgs e) { var point = this._host.InverseRenderTransform.Transform(Mouse.GetPosition(this._host.FloorScene)); UV p = new UV(point.X, point.Y); Cell cell = this._host.cellularFloor.FindCell(p); if (cell == null) { MessageBox.Show("Pick a point on the walkable field and try again!\n"); return; } switch (this._host.IsovistBarrierType) { case BarrierType.Visual: if (cell.VisualOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside visual barriers.\nTry again!"); return; } break; case BarrierType.Physical: if (cell.PhysicalOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside physical barriers.\nTry again!"); return; } break; case BarrierType.Field: if (cell.FieldOverlapState != OverlapState.Inside) { MessageBox.Show("Pick a point inside the walkable field.\nTry again!"); return; } break; case BarrierType.BarrierBuffer: if (cell.BarrierBufferOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside barrier buffers.\nTry again!"); return; } break; default: break; } try { BarrierPolygon[] barriers = new BarrierPolygon[this.radiuses.Length]; for (int i = 0; i < this.radiuses.Length; i++) { HashSet <UVLine> blocks = this._host.cellularFloor.PolygonalIsovistVisualObstacles(p, this.radiuses[i], this._host.IsovistBarrierType); barriers[i] = this._host.BIM_To_OSM.IsovistPolygon(p, this.radiuses[i], blocks); } Proxemics proxemics = new Proxemics(barriers, p); this.draw(proxemics); } catch (Exception error0) { MessageBox.Show(error0.Report()); } }
void _run_Click(object sender, RoutedEventArgs e) { #region Validate activity related input if (this._applyFilter.IsChecked.Value) { int gr = 0; if (!int.TryParse(this._gaussianRangeDefault.Text, out gr)) { MessageBox.Show("Invalid input for Gaussian filter range"); return; } else { if (gr < 2) { MessageBox.Show("Gaussian filter range should be larger than 1!"); return; } else { this._gaussianRange = gr; } } if (this._host.ViewBasedGaussianFilter.Range != gr) { this._host.ViewBasedGaussianFilter = new IsovistClippedGaussian(this._host.cellularFloor, gr); } } int _r = 0; if (!int.TryParse(this._neighborhoodRangePotential.Text, out _r)) { MessageBox.Show("Invalid input for potential field calculation range!"); return; } else { if (_r < 1) { MessageBox.Show("Potential field calculation range should be larger than 0!"); return; } else { if (this._host.FieldGenerator.Range != _r) { this._host.FieldGenerator = new Data.Visualization.SpatialDataCalculator(this._host, _r, OSMDocument.AbsoluteTolerance); } } } #endregion #region Validate simulates annealing parameters int iterationCount = 0; if (!int.TryParse(this._numberOfIterations.Text, out iterationCount)) { this.invalidInput("Number of Iterations"); return; } if (iterationCount <= 0) { this.valueSmallerThanZero("Number of Iterations"); return; } this._iterationCount = iterationCount; double minimumEnergy = 0; if (!double.TryParse(this._minimumTemperature.Text, out minimumEnergy)) { this.invalidInput("Minimum Temperature"); return; } if (minimumEnergy < 0) { MessageBox.Show("'Minimum Temperature' should not be smaller than zero!", "Invalid Input", MessageBoxButton.OK, MessageBoxImage.Error); return; } double maximumEnergy = 0; if (!double.TryParse(this._maximumTemperature.Text, out maximumEnergy)) { this.invalidInput("Maximum Temperature"); return; } if (maximumEnergy <= 0) { this.valueSmallerThanZero("Maximum Temperature"); return; } #endregion #region validation of training subset //double trainingRatio = 0; //if(!double.TryParse(this._ratioOfTrainingSubset.Text, out trainingRatio)) //{ // MessageBox.Show("Invalied 'Ratio of Training Subset'", "Invalid Input", // MessageBoxButton.OK, MessageBoxImage.Error); // return; //} //else //{ // if(trainingRatio<=0 || trainingRatio>1.0) // { // MessageBox.Show("'Ratio of Training Subset' must be larger than zero and smaller than or equal to 1", // "Invalid Input", MessageBoxButton.OK, MessageBoxImage.Error); // return; // } //} #endregion #region Validate duration and timeStep parameters double timeStep = 0; if (!double.TryParse(this._timeStep.Text, out timeStep)) { MessageBox.Show("Invalid input for 'Time Step'!", "Invalid Input", MessageBoxButton.OK, MessageBoxImage.Error); return; } else { if (timeStep <= 0) { MessageBox.Show("'Time Step' must be larger than zero!", "Invalid Input", MessageBoxButton.OK, MessageBoxImage.Error); return; } } this._timeStepValue = timeStep; this._durationValue = this._host.trailVisualization.AgentWalkingTrail.TimeIntervalBetweenInterpolatedStates;//convert seconds to hours #endregion #region Check to see if spatial data has been included int spatialDataCount = 0; foreach (Function function in this._host.cellularFloor.AllSpatialDataFields.Values) { SpatialDataField dataField = function as SpatialDataField; if (dataField != null) { if (dataField.IncludeInActivityGeneration) { spatialDataCount++; } } } if (spatialDataCount == 0) { var res = MessageBox.Show("There is no a spatial data field included to calculate cost/desirability!"); return; } #endregion #region extracting the ralated parameters and checking to see if number of parameter is not zero this.AllParameters = new HashSet <Parameter>(); if (this._velocityMagnetude.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_VelocityMagnitude.ToString()]); } if (this._angularVelocity.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_AngularVelocity.ToString()]); } if (this._bodySize.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_BodySize.ToString()]); } if (this._accelerationMagnitude.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_AccelerationMagnitude.ToString()]); } if (this._barrierRepulsionRange.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_BarrierRepulsionRange.ToString()]); } if (this._repulsionChangeRate.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_MaximumRepulsion.ToString()]); } if (this._barrierFriction.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_BarrierFriction.ToString()]); } if (this._bodyElasticity.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.GEN_AgentBodyElasticity.ToString()]); } if (this._angularDeviationCost.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.MAN_AngularDeviationCost.ToString()]); } if (this._distanceCost.IsChecked.Value) { this.AllParameters.Add(this._host.Parameters[AgentParameters.MAN_DistanceCost.ToString()]); } foreach (var item in this._host.Parameters) { foreach (var function in item.Value.LinkedFunctions) { if (function.IncludeInActivityGeneration) { this.AllParameters.Add(item.Value); break; } } } if (this.AllParameters.Count == 0) { MessageBox.Show("No parameter is included to account for the variability in the optimization process", "Parameter Not Assigned", MessageBoxButton.OK, MessageBoxImage.Error); return; } #endregion #region Trail Related Stuff this._trailIndices = new HashSet <Index>(); foreach (var item in this._host.trailVisualization.AgentWalkingTrail.ApproximatedPoints) { Index index = this._host.cellularFloor.FindIndex(item); if (this._host.cellularFloor.Cells[index.I, index.J].FieldOverlapState != OverlapState.Inside) { MessageBox.Show("The training process cannot proceed with this trail. Parts of the trail are not included in the walkable field!", "Invalid Trail", MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } else { this._trailIndices.Add(index); } } this._trailIndices = CellUtility.ExpandInWalkableField(this._host.cellularFloor, this._trailIndices); this._defaultState = this._host.trailVisualization.AgentWalkingTrail.InterpolatedStates[this._host.trailVisualization.AgentWalkingTrail.InterpolatedStates.Length - 1]; this._cellDestination = this._host.cellularFloor.FindCell(this._defaultState.Location); UV p1 = this._cellDestination; var p2 = p1 + UV.UBase * this._host.cellularFloor.CellSize; var p3 = p1 + UV.UBase * this._host.cellularFloor.CellSize + UV.VBase * this._host.cellularFloor.CellSize; var p4 = p1 + UV.VBase * this._host.cellularFloor.CellSize; this._destination = new BarrierPolygon(new UV[] { p1, p2, p3, p4 }); #endregion //execute visibility changes in the interface Dispatcher.Invoke(new Action(() => { this._run_close.SetValue(Button.VisibilityProperty, System.Windows.Visibility.Collapsed); this._run_close.SetValue(Button.ContentProperty, "Close"); this._mainInterface.SetValue(Grid.VisibilityProperty, System.Windows.Visibility.Collapsed); this._progressPanel.SetValue(StackPanel.VisibilityProperty, System.Windows.Visibility.Visible); }), DispatcherPriority.ContextIdle); //unregister run button event this._run_close.Click -= this._run_Click; //create annealing SimulatedAnnealingSolver solver = new SimulatedAnnealingSolver(this.AllParameters); //register UI update event for best fitness changes solver.BestFitnessUpdated += solver_BestFitnessUpdated; //register UI update event for fitness changes solver.FitnessUpdated += solver_FitnessUpdated; //Setting the initial iteration to zero this._counter = 0; //initializing the trial visualization this._host.trailVisualization.InitiateTrainingVisualization(); //running the annealing process solver.Solve(minimumEnergy, maximumEnergy, iterationCount, this.measureFitnessWithInterfaceUpdate); //unregister UI update event for fitness changes solver.BestFitnessUpdated -= solver_BestFitnessUpdated; //unregister UI update event for fitness changes solver.FitnessUpdated -= solver_FitnessUpdated; //showing the close btn. The close event is not registered yet Dispatcher.Invoke(new Action(() => { this._run_close.SetValue(Button.VisibilityProperty, System.Windows.Visibility.Visible); }), DispatcherPriority.ContextIdle); //Show the last parameter setting on UI this._sb.Clear(); foreach (var item in this.AllParameters) { this._sb.AppendLine(item.ToString()); } this._updateMessage.SetValue(TextBlock.TextProperty, this._sb.ToString()); //set Window closing events this._run_close.Click += (s, e1) => { var result = MessageBox.Show("Do you want to clear the training data from screen?", "", MessageBoxButton.YesNo, MessageBoxImage.Exclamation); if (result == MessageBoxResult.Yes) { this._host.trailVisualization.TerminateTrainingVisualization(); } this.Close(); }; }
/// <summary> /// Gets the Isovist polygon. /// </summary> /// <param name="vantagePoint">The vantage point.</param> /// <param name="viewDepth">The view depth.</param> /// <param name="edges">The edges.</param> /// <returns>BarrierPolygons.</returns> public BarrierPolygon IsovistPolygon(UV vantagePoint, double viewDepth, HashSet <UVLine> edges) { /*first and expand and shrink operation is performed to merge the shadowing edges*/ double expandShrinkFactor = Math.Pow(10.0, this.PolygonalBooleanPrecision) * UnitConversion.Convert(0.075, Length_Unit_Types.FEET, UnitType); //offsetting the excluded area of each edge INTPolygons offsetedPolygons = new INTPolygons(); ClipperOffset clipperOffset = new ClipperOffset(); foreach (UVLine edgeItem in edges) { clipperOffset.AddPath(this.excludedArea(vantagePoint, viewDepth + 1, edgeItem), ClipperLib.JoinType.jtMiter, EndType.etClosedPolygon); INTPolygons plygns = new INTPolygons(); clipperOffset.Execute(ref plygns, expandShrinkFactor); offsetedPolygons.AddRange(plygns); clipperOffset.Clear(); } //Unioning the expanded exclusions INTPolygons offsetUnioned = new INTPolygons(); Clipper c = new Clipper(); c.AddPaths(offsetedPolygons, PolyType.ptSubject, true); c.Execute(ClipType.ctUnion, offsetUnioned, PolyFillType.pftNonZero, PolyFillType.pftNonZero); //shrink the polygons to retain their original size INTPolygons results = new INTPolygons(); clipperOffset.Clear(); clipperOffset.AddPaths(offsetUnioned, JoinType.jtMiter, EndType.etClosedPolygon); clipperOffset.Execute(ref results, -expandShrinkFactor); clipperOffset.Clear(); offsetUnioned.Clear(); /* * What ever is a hole in the resulting mereged polygon is the visibility polygon * Now we classify the polygons based on being a hole or not */ //filtering out the holes that do not include the center INTPolygons holesNOT = new INTPolygons(); INTPolygons holesIncludingCenter = new INTPolygons(); IntPoint iCenter = ConvertUVToIntPoint(vantagePoint); foreach (INTPolygon item in results) { if (!Clipper.Orientation(item)) { if (Clipper.PointInPolygon(iCenter, item) == 1) { holesIncludingCenter.Add(item); } } else { holesNOT.Add(item); } } if (holesIncludingCenter.Count == 0) { //there is no hole. The shadow polygones should clip the potential field of visibility (i.e. circle) by an subtraction operation INTPolygon circle = createCircle(vantagePoint, viewDepth); //subtraction c.Clear(); c.AddPath(circle, PolyType.ptSubject, true); c.AddPaths(holesNOT, PolyType.ptClip, true); INTPolygons isovistPolygon = new INTPolygons(); c.Execute(ClipType.ctDifference, isovistPolygon); //searching for a polygon that includes the center foreach (INTPolygon item in isovistPolygon) { if (Clipper.PointInPolygon(iCenter, item) == 1) { BarrierPolygon isovist = this.ConvertINTPolygonToBarrierPolygon(item); results = null; c = null; clipperOffset = null; offsetedPolygons = null; circle = null; holesNOT = null; holesIncludingCenter = null; isovistPolygon = null; return(isovist); } } MessageBox.Show(string.Format("Isovist not found!\nNo hole detected\n{0} polygons can be isovist", isovistPolygon.Count.ToString())); } else if (holesIncludingCenter.Count == 1) { INTPolygons isovistPolygon = holesIncludingCenter; foreach (INTPolygon item in isovistPolygon) { if (Clipper.PointInPolygon(iCenter, item) == 1) { item.Reverse(); BarrierPolygon isovist = this.ConvertINTPolygonToBarrierPolygon(item); results = null; c = null; clipperOffset = null; offsetedPolygons = null; holesNOT = null; holesIncludingCenter = null; isovistPolygon = null; return(isovist); } } MessageBox.Show(string.Format("Isovist not found!\nOne hole detected\n{0} polygons can be isovist", isovistPolygon.Count.ToString())); } else if (holesIncludingCenter.Count > 1) { MessageBox.Show("Isovist not found!\nMore than one hole found that can include the vantage point"); } return(null); }
/// <summary> /// Calculates the activity (i.e. potential field) with respect to distance, static cost and angle. /// </summary> /// <param name="destination">The destination.</param> /// <param name="destinationArea">The destination area.</param> /// <param name="defaultState">The default state.</param> /// <param name="name">The name.</param> /// <param name="angleCost">The angle cost.</param> /// <param name="radius">The radius.</param> /// <returns>Activity.</returns> /// <exception cref="System.ArgumentException">Negative cost for edge found: " + edgeCost.ToString() + /// "\nP1: " + /// this._cellularFloor.FindCell(current).Origin.ToString() + "\nP2: " + this._cellularFloor.FindCell(neighborIndex).Origin.ToString() + /// "\nDistance: " + this._cellularFloor.FindCell(current).Origin.DistanceTo(this._cellularFloor.FindCell(neighborIndex).Origin).ToString()</exception> public Activity GetDynamicActivity(Cell destination, BarrierPolygon destinationArea, StateBase defaultState, string name, double angleCost, double radius) { var timer = new System.Diagnostics.Stopwatch(); timer.Start(); //Calculating static costs double distance_cost_factor = Parameter.DefaultParameters[AgentParameters.MAN_DistanceCost].Value; if (distance_cost_factor < 0) { throw new ArgumentException("Parameter MAN_DistanceCost cannot have a negative value: " + distance_cost_factor.ToString()); } Dictionary <Cell, double> costs = this._host.cellularFloor.GetStaticCost(); #region set the initial potential to positive infinity; define heap and labeled where the potential is zero; SortedSet <WeightedIndex> heap = new SortedSet <WeightedIndex>(); WeightedIndex[,] indices = new WeightedIndex[this._host.cellularFloor.GridWidth, this._host.cellularFloor.GridHeight]; bool[,] marked = new bool[this._host.cellularFloor.GridWidth, this._host.cellularFloor.GridHeight]; UV[,] previousOrigins = new UV[this._host.cellularFloor.GridWidth, this._host.cellularFloor.GridHeight]; for (int i = 0; i < this._host.cellularFloor.GridWidth; i++) { for (int j = 0; j < this._host.cellularFloor.GridHeight; j++) { indices[i, j] = new WeightedIndex(i, j, double.PositiveInfinity); } } indices[destination.CellToIndex.I, destination.CellToIndex.J].WeightingFactor = 0; marked[destination.CellToIndex.I, destination.CellToIndex.J] = true; heap.Add(indices[destination.CellToIndex.I, destination.CellToIndex.J]); #endregion var radiusSquared = radius * radius; var target = this._host.cellularFloor.Cells[destination.CellToIndex.I, destination.CellToIndex.J]; while (heap.Count != 0) { var current = heap.Min; heap.Remove(current); marked[current.I, current.J] = true; UV currentDirection = null; if (previousOrigins[current.I, current.J] != null) { currentDirection = this._host.cellularFloor.Cells[current.I, current.J] - previousOrigins[current.I, current.J]; currentDirection.Unitize(); } foreach (var item in this.Rays.Keys) { int I = current.I + item.I; int J = current.J + item.J; if (this._host.cellularFloor.ContainsCell(I, J) && this._host.cellularFloor.Cells[I, J].FieldOverlapState == OverlapState.Inside && !marked[I, J] && radiusSquared >= UV.GetLengthSquared(this._host.cellularFloor.Cells[I, J], target)) { var neighborIndex = indices[I, J]; double edgeCost = this.getStaticCostOfEdge(neighborIndex, current, distance_cost_factor, costs); if (edgeCost <= 0) { throw new ArgumentException("Negative cost for edge found: " + edgeCost.ToString() + "\nP1: " + this._host.cellularFloor.FindCell(current).ToString() + "\nP2: " + this._host.cellularFloor.FindCell(neighborIndex).ToString() + "\nDistance: " + this._host.cellularFloor.FindCell(current).DistanceTo(this._host.cellularFloor.FindCell(neighborIndex)).ToString()); } double newPotential = current.WeightingFactor + edgeCost; if (currentDirection != null) { var newDirection = this._host.cellularFloor.Cells[current.I, current.J] - this._host.cellularFloor.Cells[I, J]; newDirection.Unitize(); double angle = Math.Abs(newDirection.AngleTo(currentDirection)); newPotential += angleCost * (Math.PI - Math.Abs(angle)); } if (!heap.Contains(neighborIndex)) { previousOrigins[neighborIndex.I, neighborIndex.J] = this._host.cellularFloor.Cells[current.I, current.J]; neighborIndex.WeightingFactor = newPotential; heap.Add(neighborIndex); } else { if (neighborIndex.WeightingFactor > newPotential) { previousOrigins[neighborIndex.I, neighborIndex.J] = this._host.cellularFloor.Cells[current.I, current.J]; heap.Remove(neighborIndex); neighborIndex.WeightingFactor = newPotential; heap.Add(neighborIndex); } } } } } heap = null; marked = null; costs = null; previousOrigins = null; Dictionary <Cell, double> potentials = new Dictionary <Cell, double>(); foreach (var item in indices) { if (!double.IsInfinity(item.WeightingFactor)) { potentials.Add(this._host.cellularFloor.Cells[item.I, item.J], item.WeightingFactor); } } indices = null; timer.Stop(); this.PotentialFieldGenerationTime = timer.Elapsed.TotalMilliseconds; return(new Activity(potentials, new HashSet <Cell> { destination }, destinationArea, defaultState, name, this._host.cellularFloor)); }
/// <summary> /// Gets the static potential field for training. /// </summary> /// <param name="destination">The destination.</param> /// <param name="destinationArea">The destination area.</param> /// <param name="defaultState">The default state.</param> /// <param name="name">The name.</param> /// <param name="trail">The trail.</param> /// <returns>Activity.</returns> /// <exception cref="System.ArgumentException">Negative cost for edge found: " + edgeCost.ToString() + /// "\nP1: " + /// this._cellularFloor.FindCell(current).Origin.ToString() + "\nP2: " + this._cellularFloor.FindCell(neighborIndex).Origin.ToString() + /// "\nDistance: " + this._cellularFloor.FindCell(current).Origin.DistanceTo(this._cellularFloor.FindCell(neighborIndex).Origin).ToString()</exception> public Activity GetStaticPotentialFieldForTraining(Cell destination, BarrierPolygon destinationArea, StateBase defaultState, string name, HashSet <Index> trail) { var timer = new System.Diagnostics.Stopwatch(); timer.Start(); //Calculating static costs double distance_cost_factor = Parameter.DefaultParameters[AgentParameters.MAN_DistanceCost].Value; if (distance_cost_factor < 0) { throw new ArgumentException("Parameter MAN_DistanceCost cannot have a negative value: " + distance_cost_factor.ToString()); } Dictionary <Cell, double> costs = this._host.cellularFloor.GetStaticCost(); #region set the initial potential to positive infinity; define heap and labeled where the potential is zero; SortedSet <WeightedIndex> heap = new SortedSet <WeightedIndex>(); WeightedIndex[,] indices = new WeightedIndex[this._host.cellularFloor.GridWidth, this._host.cellularFloor.GridHeight]; bool[,] marked = new bool[this._host.cellularFloor.GridWidth, this._host.cellularFloor.GridHeight]; for (int i = 0; i < this._host.cellularFloor.GridWidth; i++) { for (int j = 0; j < this._host.cellularFloor.GridHeight; j++) { indices[i, j] = new WeightedIndex(i, j, double.PositiveInfinity); } } var destinations = new HashSet <Cell> { destination }; foreach (var item in destinations) { indices[item.CellToIndex.I, item.CellToIndex.J].WeightingFactor = 0; marked[item.CellToIndex.I, item.CellToIndex.J] = true; heap.Add(indices[item.CellToIndex.I, item.CellToIndex.J]); } #endregion HashSet <Index> trailIndices = new HashSet <Index>(trail); while (!(heap.Count == 0 || trailIndices.Count == 0)) { var current = heap.Min; heap.Remove(current); marked[current.I, current.J] = true; if (trailIndices.Contains(current)) { trailIndices.Remove(current); } foreach (var item in this.Rays.Keys) { int I = current.I + item.I; int J = current.J + item.J; if (this._host.cellularFloor.ContainsCell(I, J) && this._host.cellularFloor.Cells[I, J].FieldOverlapState == OverlapState.Inside && !marked[I, J]) { var neighborIndex = indices[I, J]; double edgeCost = this.getStaticCostOfEdge(neighborIndex, current, distance_cost_factor, costs); if (edgeCost <= 0) { throw new ArgumentException("Negative cost for edge found: " + edgeCost.ToString() + "\nP1: " + this._host.cellularFloor.FindCell(current).ToString() + "\nP2: " + this._host.cellularFloor.FindCell(neighborIndex).ToString() + "\nDistance: " + this._host.cellularFloor.FindCell(current).DistanceTo(this._host.cellularFloor.FindCell(neighborIndex)).ToString()); } double newPotential = current.WeightingFactor + edgeCost; if (!heap.Contains(neighborIndex)) { neighborIndex.WeightingFactor = newPotential; heap.Add(neighborIndex); } else { if (neighborIndex.WeightingFactor > newPotential) { heap.Remove(neighborIndex); neighborIndex.WeightingFactor = newPotential; heap.Add(neighborIndex); } } } } } heap = null; marked = null; costs = null; Dictionary <Cell, double> potentials = new Dictionary <Cell, double>(); foreach (var item in indices) { if (!double.IsInfinity(item.WeightingFactor)) { potentials.Add(this._host.cellularFloor.Cells[item.I, item.J], item.WeightingFactor); } } indices = null; timer.Stop(); this.PotentialFieldGenerationTime = timer.Elapsed.TotalMilliseconds; return(new Activity(potentials, destinations, destinationArea, defaultState, name, this._host.cellularFloor)); }
private void mouseLeftButtonDown_GetPolygonalIsovist(object sender, MouseButtonEventArgs e) { var point = this._host.InverseRenderTransform.Transform(Mouse.GetPosition(this._host.FloorScene)); UV p = new UV(point.X, point.Y); Cell cell = this._host.cellularFloor.FindCell(p); if (cell == null) { MessageBox.Show("Pick a point on the walkable field and try again!\n"); return; } switch (this._host.IsovistBarrierType) { case BarrierType.Visual: if (cell.VisualOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside visual barriers.\nTry again!"); return; } break; case BarrierType.Physical: if (cell.PhysicalOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside physical barriers.\nTry again!"); return; } break; case BarrierType.Field: if (cell.FieldOverlapState != OverlapState.Inside) { MessageBox.Show("Pick a point inside the walkable field.\nTry again!"); return; } break; case BarrierType.BarrierBuffer: if (cell.BarrierBufferOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside barrier buffers.\nTry again!"); return; } break; default: break; } this._children.Clear(); var timer = new System.Diagnostics.Stopwatch(); try { timer.Start(); HashSet <UVLine> blocks = this._host.cellularFloor.PolygonalIsovistVisualObstacles(p, this._host.IsovistDepth, this._host.IsovistBarrierType); BarrierPolygon isovistPolygon = this._host.BIM_To_OSM.IsovistPolygon(p, this._host.IsovistDepth, blocks); IsovistPolygon newIsovistPolygon = new IsovistPolygon(isovistPolygon.BoundaryPoints, p); timer.Stop(); this._host.IsovistInformation = new IsovistInformation(IsovistInformation.IsovistType.Polygonal, timer.Elapsed.TotalMilliseconds, isovistPolygon.GetArea(), isovistPolygon.GetPerimeter()); this.draw(newIsovistPolygon); } catch (Exception error0) { this._host.IsovistInformation = null; MessageBox.Show(error0.Message); } timer = null; }
private void drawInRevit() { var timer = new System.Diagnostics.Stopwatch(); this._host.Hide(); UV p = this._host.OSM_to_BIM.PickPoint("Pick a vantage point to draw polygonal Isovist"); Cell cell = this._host.cellularFloor.FindCell(p); if (cell == null) { MessageBox.Show("Pick a point on the walkable field and try again!\n"); this._host.ShowDialog(); return; } switch (this._host.IsovistBarrierType) { case BarrierType.Visual: if (cell.VisualOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside visual barriers.\nTry again!"); this._host.ShowDialog(); return; } break; case BarrierType.Physical: if (cell.PhysicalOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside physical barriers.\nTry again!"); this._host.ShowDialog(); return; } break; case BarrierType.Field: if (cell.FieldOverlapState != OverlapState.Inside) { MessageBox.Show("Pick a point inside the walkable field.\nTry again!"); this._host.ShowDialog(); return; } break; case BarrierType.BarrierBuffer: if (cell.BarrierBufferOverlapState != OverlapState.Outside) { MessageBox.Show("Pick a point outside barrier buffers.\nTry again!"); this._host.ShowDialog(); return; } break; default: break; } try { timer.Start(); HashSet <UVLine> blocks = this._host.cellularFloor.PolygonalIsovistVisualObstacles(p, this._host.IsovistDepth, this._host.IsovistBarrierType); BarrierPolygon isovistPolygon = this._host.BIM_To_OSM.IsovistPolygon(p, this._host.IsovistDepth, blocks); timer.Stop(); isovistPolygon.Visualize(this._host.OSM_to_BIM, this._host.BIM_To_OSM.PlanElevation); this._host.IsovistInformation = new IsovistInformation(IsovistInformation.IsovistType.Polygonal, timer.Elapsed.TotalMilliseconds, isovistPolygon.GetArea(), isovistPolygon.GetPerimeter()); } catch (Exception error0) { this._host.IsovistInformation = null; MessageBox.Show(error0.Message); } timer = null; this._host.ShowDialog(); }