Exemplo n.º 1
0
        /// <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&lt;BarrierPolygons&gt;.</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;
 }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 11
0
        /// <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));
        }
Exemplo n.º 12
0
        /// <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();
        }