/// <summary>
        /// Returns a ordered array of indices that the ray intersects with. These indices include the overlapping length of the ray as their weighting factor.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <param name="target">The target.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>WeightedIndex[].</returns>
        public static WeightedIndex[] LoadWeightingFactors(UV origin, UV target, CellularFloorBaseGeometry cellularFloor, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            UV     direction = target - origin;
            double length    = direction.GetLength();

            direction /= length;
            Ray ray = new Ray(origin, direction, cellularFloor.Origin,
                              cellularFloor.CellSize, tolerance);
            List <WeightedIndex> weightedIndices = new List <WeightedIndex>();

            while (ray.Length + tolerance < length)
            {
                double d1 = ray.Length;
                UV     p1 = ray.PointAt(d1);
                ray.Next(tolerance);
                double d2 = ray.Length;
                UV     p2 = ray.PointAt(d2);
                UV     p  = (p1 + p2) / 2;
                double w  = d2 - d1;
                if (w > tolerance)
                {
                    double        i             = (p.U - cellularFloor.Origin.U) / cellularFloor.CellSize;
                    int           I             = (int)i;
                    double        j             = (p.V - cellularFloor.Origin.V) / cellularFloor.CellSize;
                    int           J             = (int)j;
                    WeightedIndex weightedIndex = new WeightedIndex(I, J, w);
                    weightedIndices.Add(weightedIndex);
                }
            }
            return(weightedIndices.ToArray());
        }
示例#2
0
        /// <summary>
        /// Visualizes the intersection in BIM environment.
        /// </summary>
        /// <param name="visualizer">The visualizer.</param>
        /// <param name="rayOrigin">The ray origin.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <param name="elevation">The elevation.</param>
        /// <param name="pointSize">Size of the point.</param>
        public void Visualize(I_OSM_To_BIM visualizer, UV rayOrigin, CellularFloorBaseGeometry cellularFloor, double elevation, double pointSize = .3)
        {
            switch (this.Type)
            {
            case BarrierType.Visual:
                //visualizer.VisualizeBoundary(cellularFloor.VisualBarriers[this.BarrierIndex].BoundaryPoints, elevation);

                visualizer.VisualizeLine(cellularFloor.VisualBarrierEdges[this.EdgeIndexInCellularFloor], elevation);
                break;

            case BarrierType.Physical:
                //visualizer.VisualizeBoundary(cellularFloor.PhysicalBarriers[this.BarrierIndex].BoundaryPoints, elevation);

                visualizer.VisualizeLine(cellularFloor.PhysicalBarrierEdges[this.EdgeIndexInCellularFloor], elevation);
                break;

            case BarrierType.Field:
                //visualizer.VisualizeBoundary(cellularFloor.PhysicalBarriers[this.BarrierIndex].BoundaryPoints, elevation);

                visualizer.VisualizeLine(cellularFloor.FieldBarrierEdges[this.EdgeIndexInCellularFloor], elevation);
                break;

            default:
                break;
            }
            //visualizer.VisualizePoint(IntersectingPoint, pointSize, elevation);
            visualizer.VisualizeLine(new UVLine(rayOrigin, this.IntersectingPoint), elevation);
        }
        /// <summary>
        /// Determines if a cell is on the edges of a cell collections
        /// </summary>
        /// <param name="cellID">The ID of the cell</param>
        /// <param name="cellularFloor">The CellularFloorBaseGeometry to which this cell belongs</param>
        /// <param name="collection">Cell ID collection</param>
        /// <returns>true for being on the edge false for not being on the edge</returns>
        private static bool onEdge(int cellID, CellularFloorBaseGeometry cellularFloor, HashSet <int> collection)
        {
            var index = cellularFloor.FindIndex(cellID);

            if (index.I == 0 || index.I == cellularFloor.GridWidth - 1 || index.J == 0 || index.J == cellularFloor.GridHeight - 1)
            {
                return(true);
            }
            int iMin = (index.I == 0) ? 0 : index.I - 1;
            int iMax = (index.I == cellularFloor.GridWidth - 1) ? cellularFloor.GridWidth - 1 : index.I + 1;
            int jMin = (index.J == 0) ? 0 : index.J - 1;
            int jMax = (index.J == cellularFloor.GridHeight - 1) ? cellularFloor.GridHeight - 1 : index.J + 1;

            for (int i = iMin; i <= iMax; i++)
            {
                for (int j = jMin; j <= jMax; j++)
                {
                    if (cellularFloor.ContainsCell(i, j))
                    {
                        if (!collection.Contains(cellularFloor.Cells[i, j].ID))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// Extracts the edges of a collection of cells
        /// </summary>
        /// <param name="cellularFloor">The CellularFloorBaseGeometry to which the cells belong</param>
        /// <param name="collection">A collection of cells IDs to find its edges</param>
        /// <returns>A collection of cell IDs on the edge</returns>
        public static HashSet <int> GetEdgeOfField(CellularFloorBaseGeometry cellularFloor, HashSet <int> collection)
        {
            HashSet <int> edge = new HashSet <int>();

            foreach (var item in collection)
            {
                if (CellUtility.onEdge(item, cellularFloor, collection))
                {
                    edge.Add(item);
                }
            }
            return(edge);
        }
        /// <summary>
        /// Extracts the edges of a collection of cells
        /// </summary>
        /// <param name="cellularFloor">The CellularFloorBaseGeometry to which the cells belong</param>
        /// <param name="collection">A collection of cells to find its edges</param>
        /// <returns>A collection of cell indices on the edge</returns>
        public static HashSet <Index> GetIndexEdgeOfField(CellularFloorBaseGeometry cellularFloor, HashSet <Cell> collection)
        {
            HashSet <Index> edge = new HashSet <Index>();

            foreach (var item in collection)
            {
                Index index = cellularFloor.FindIndex(item);
                if (CellUtility.onEdge(index, cellularFloor, collection))
                {
                    edge.Add(index);
                }
            }
            return(edge);
        }
 /// <summary>
 /// Determines if a cell is on the edges of a cell collections
 /// </summary>
 /// <param name="index">The index of the cell</param>
 /// <param name="cellularFloor">The CellularFloorBaseGeometry to which this cell belongs</param>
 /// <param name="collection">Cell ID collection</param>
 /// <returns>true for being on the edge false for not being on the edge</returns>
 private static bool onEdge(Index index, CellularFloorBaseGeometry cellularFloor, HashSet <Cell> collection)
 {
     foreach (Index item in Index.Neighbors)
     {
         Index neighbor = item + index;
         if (cellularFloor.ContainsCell(neighbor))
         {
             if (!collection.Contains(cellularFloor.Cells[neighbor.I, neighbor.J]))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        /// <summary>
        /// Gets the boundary polygons of a collection of cells.
        /// </summary>
        /// <param name="cellIDs">The visible cells.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <returns>List&lt;BarrierPolygons&gt;.</returns>
        public static List <BarrierPolygon> GetBoundary(ICollection <int> cellIDs, CellularFloorBaseGeometry cellularFloor)
        {
            Dictionary <UVLine, int> guid = new Dictionary <UVLine, int>();

            foreach (var item in cellIDs)
            {
                var lines = cellularFloor.CellToLines(cellularFloor.FindCell(item));
                foreach (var line in lines)
                {
                    if (guid.ContainsKey(line))
                    {
                        guid[line]++;
                    }
                    else
                    {
                        guid.Add(line, 1);
                    }
                }
            }
            List <UVLine> boundaryLines = new List <UVLine>();

            foreach (KeyValuePair <UVLine, int> item in guid)
            {
                if (item.Value == 1)
                {
                    boundaryLines.Add(item.Key);
                }
            }
            guid.Clear();
            guid = null;
            var plines = PLine.ExtractPLines(boundaryLines);
            List <BarrierPolygon> boundary = new List <BarrierPolygon>();

            foreach (PLine item in plines)
            {
                var oneBoundary = item.Simplify(cellularFloor.CellSize / 10);
                if (oneBoundary != null)
                {
                    boundary.Add(new BarrierPolygon(oneBoundary.ToArray()));
                }
            }
            boundaryLines.Clear();
            boundaryLines = null;
            return(boundary);
        }
        /// <summary>
        /// Creats an instance of the CollisionAnalyzer.
        /// </summary>
        /// <param name="point">The agent or target location</param>
        /// <param name="cellularFloor">The CellularFloorBaseGeometry which includes the agent or target</param>
        /// <param name="barrierType">Barrier type</param>
        /// <returns>An instance of the CollisionAnalyzer which can be null</returns>
        public static CollisionAnalyzer GetCollidingEdge(UV point, CellularFloorBaseGeometry cellularFloor, BarrierType barrierType)
        {
            Cell cell = cellularFloor.FindCell(point);

            if (cell == null)
            {
                return(null);
            }
            switch (barrierType)
            {
            case BarrierType.Visual:
                if (cell.VisualOverlapState == OverlapState.Inside)
                {
                    return(null);
                }
                break;

            case BarrierType.Physical:
                if (cell.PhysicalOverlapState == OverlapState.Inside)
                {
                    return(null);
                }
                break;

            case BarrierType.Field:
                if (cell.FieldOverlapState == OverlapState.Outside)
                {
                    //cell.Visualize(MainDocument.TargetVisualizer, Cell.Size, Cell.Size, 0);
                    return(null);
                }
                break;

            case BarrierType.BarrierBuffer:
                return(null);
            }
            var colision = new CollisionAnalyzer(point, cell, cellularFloor, barrierType);

            if (colision.Barrrier == null)
            {
                return(null);
            }
            return(colision);
        }
        /// <summary>
        /// Get a list of ordered cells on the edge of a cell collection
        /// </summary>
        /// <param name="cellularFloor">The CellularFloorBaseGeometry to which the cells belong</param>
        /// <param name="collection">A collection of cells to find its edges</param>
        /// <returns>An ordered list of cells</returns>
        public static List <Cell> GetOrderedEdge(CellularFloorBaseGeometry cellularFloor, HashSet <Cell> collection)
        {
            HashSet <Index> edge = CellUtility.GetIndexEdgeOfField(cellularFloor, collection);
            IndexGraph      indexGraph = new IndexGraph(edge);
            int             zero = 0, one = 0, two = 0, three = 0, four = 0;

            foreach (var item in indexGraph.IndexNodeMap.Values)
            {
                switch (item.Connections.Count)
                {
                case 0:
                    zero++;
                    break;

                case 1:
                    one++;
                    break;

                case 2:
                    two++;
                    break;

                case 3:
                    three++;
                    break;

                case 4:
                    four++;
                    break;

                default:
                    break;
                }
            }
            MessageBox.Show(string.Format("Zero: {0}\nOne: {1}\nTwo: {2}\nThree: {3}\nFour: {4}",
                                          zero.ToString(), one.ToString(), two.ToString(), three.ToString(), four.ToString()));
            return(null);
        }
        /// <summary>
        /// Creats an instance of the CollisionAnalyzer. For internal use only.
        /// </summary>
        /// <param name="point">The agent or target location</param>
        /// <param name="cell">The cell to which the point belongs</param>
        /// <param name="cellularFloor">The CellularFloorBaseGeometry which includes the agent or target</param>
        /// <param name="barrierType">Barrier type</param>
        internal CollisionAnalyzer(UV point, Cell cell, CellularFloorBaseGeometry cellularFloor, BarrierType barrierType)
        {
            this.CollisionOccured = false;
            this.Location         = point;
            Index index = cellularFloor.FindIndex(cell);
            int   I     = index.I + 2;

            //int I = index.I + 1;
            I = Math.Min(I, cellularFloor.GridWidth - 1);
            int J = index.J + 2;

            //int J = index.J + 1;
            J       = Math.Min(J, cellularFloor.GridHeight - 1);
            index.I = Math.Max(0, index.I - 1);
            index.J = Math.Max(0, index.J - 1);
            double DistanceSquared = double.PositiveInfinity;

            for (int i = index.I; i <= I; i++)
            {
                for (int j = index.J; j <= J; j++)
                {
                    switch (barrierType)
                    {
                    case BarrierType.Visual:
                        if (cellularFloor.Cells[i, j].VisualOverlapState == OverlapState.Outside)
                        {
                            foreach (int item in cellularFloor.Cells[i, j].VisualBarrierEdgeIndices)
                            {
                                double d = point.GetDistanceSquared(cellularFloor.VisualBarrierEdges[item]);
                                if (d < DistanceSquared)
                                {
                                    DistanceSquared = d;
                                    Barrrier        = cellularFloor.VisualBarrierEdges[item];
                                }
                            }
                        }
                        break;

                    case BarrierType.Physical:
                        if (cellularFloor.Cells[i, j].PhysicalOverlapState != OverlapState.Outside)
                        {
                            foreach (int item in cellularFloor.Cells[i, j].PhysicalBarrierEdgeIndices)
                            {
                                double d = point.GetDistanceSquared(cellularFloor.PhysicalBarrierEdges[item]);
                                if (d < DistanceSquared)
                                {
                                    DistanceSquared = d;
                                    Barrrier        = cellularFloor.PhysicalBarrierEdges[item];
                                }
                            }
                        }
                        break;

                    case BarrierType.Field:
                        if (cellularFloor.Cells[i, j].BarrierBufferOverlapState != OverlapState.Inside)
                        {
                            foreach (int item in cellularFloor.Cells[i, j].FieldBarrierEdgeIndices)
                            {
                                double d = point.GetDistanceSquared(cellularFloor.FieldBarrierEdges[item]);
                                if (d < DistanceSquared)
                                {
                                    DistanceSquared = d;
                                    Barrrier        = cellularFloor.FieldBarrierEdges[item];
                                }
                            }
                        }
                        break;
                    }
                }
            }
            if (!double.IsPositiveInfinity(DistanceSquared) &&
                this.Barrrier != null)
            {
                bool isEndpoint = false;
                this.ClosestPointOnBarrier    = point.GetClosestPoint(this.Barrrier, ref isEndpoint);
                this.IsClosestPointAnEndPoint = isEndpoint;
                this.NormalizedRepulsion      = this.Location - this.ClosestPointOnBarrier;
                this.DistanceToBarrier        = this.NormalizedRepulsion.GetLength();
                this.NormalizedRepulsion     /= this.DistanceToBarrier;
            }
        }
示例#11
0
        /// <summary>
        /// Checks the existence of a line of sight between two points.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <param name="target">The target.</param>
        /// <param name="barrierType">Type of the barrier.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns><c>true</c> if visible, <c>false</c> otherwise.</returns>
        public static bool Visible(UV origin, UV target, BarrierType barrierType, CellularFloorBaseGeometry cellularFloor, double tolerance = OSMDocument.AbsoluteTolerance)
        {
            UV     direction = target - origin;
            double length    = direction.GetLength();

            direction /= length;
            Ray ray = new Ray(origin, direction, cellularFloor.Origin,
                              cellularFloor.CellSize, tolerance);

            while (ray.Length + tolerance < length)
            {
                Index index = ray.NextIndex(cellularFloor.FindIndex, tolerance);
                if (cellularFloor.ContainsCell(index))
                {
                    switch (barrierType)
                    {
                    case BarrierType.Visual:
                        if (cellularFloor.Cells[index.I, index.J].VisualOverlapState == OverlapState.Overlap)
                        {
                            foreach (int item in cellularFloor.Cells[index.I, index.J].VisualBarrierEdgeIndices)
                            {
                                double?distance = ray.DistanceToForIsovist(cellularFloor.VisualBarrierEdges[item], tolerance);
                                if (distance != null && distance.Value + tolerance < length)
                                {
                                    UVLine hitEdge = cellularFloor.VisualBarrierEdges[item];
                                    return(false);
                                }
                            }
                        }
                        break;

                    case BarrierType.Physical:
                        if (cellularFloor.Cells[index.I, index.J].PhysicalOverlapState == OverlapState.Overlap)
                        {
                            foreach (int item in cellularFloor.Cells[index.I, index.J].PhysicalBarrierEdgeIndices)
                            {
                                double?distance = ray.DistanceToForIsovist(cellularFloor.PhysicalBarrierEdges[item], tolerance);
                                if (distance != null && distance.Value + tolerance < length)
                                {
                                    UVLine hitEdge = cellularFloor.PhysicalBarrierEdges[item];
                                    return(false);
                                }
                            }
                        }
                        break;

                    case BarrierType.Field:
                        if (cellularFloor.Cells[index.I, index.J].FieldOverlapState == OverlapState.Overlap)
                        {
                            foreach (int item in cellularFloor.Cells[index.I, index.J].FieldBarrierEdgeIndices)
                            {
                                double?distance = ray.DistanceToForIsovist(cellularFloor.FieldBarrierEdges[item], tolerance);
                                if (distance != null && distance.Value + tolerance < length)
                                {
                                    UVLine hitEdge = cellularFloor.FieldBarrierEdges[item];
                                    return(false);
                                }
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            return(true);
        }
示例#12
0
        /// <summary>
        /// Determines whether a visual the event is raised.
        /// </summary>
        /// <param name="currentState">The current state of the agent.</param>
        /// <param name="visibilityCosineFactor">The visibility cosine factor.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <returns><c>true</c> if visual the event is raised, <c>false</c> otherwise.</returns>
        public bool VisualEventRaised(StateBase currentState, double visibilityCosineFactor, CellularFloorBaseGeometry cellularFloor)
        {
            var vantageCell = cellularFloor.FindCell(currentState.Location);

            if (!this.AllVisibleCells.Contains(vantageCell.ID))
            {
                return(false);
            }
            bool raised = false;

            foreach (var cellID in this.ReferencedVantageCells[vantageCell.ID])
            {
                UV targetCell = cellularFloor.FindCell(cellID);
                UV direction  = targetCell - currentState.Location;
                direction.Unitize();
                if (direction.DotProduct(currentState.Direction) >= visibilityCosineFactor)
                {
                    raised = true;
                    break;
                }
            }
            return(raised);
        }
示例#13
0
        /// <summary>
        /// Targets the visibility test.
        /// </summary>
        /// <param name="currentState">The current state of the agent.</param>
        /// <param name="visibilityCosineFactor">The visibility cosine factor.</param>
        /// <param name="cellularFloor">The cellular floor.</param>
        /// <returns>UV.</returns>
        public UV TargetVisibilityTest(StateBase currentState, double visibilityCosineFactor, CellularFloorBaseGeometry cellularFloor)
        {
            var vantageCell = cellularFloor.FindCell(currentState.Location);

            if (!this.AllVisibleCells.Contains(vantageCell.ID))
            {
                return(null);
            }
            UV target = null;

            foreach (var cellID in this.ReferencedVantageCells[vantageCell.ID])
            {
                UV targetCell = cellularFloor.FindCell(cellID);
                UV direction  = targetCell - currentState.Location;
                direction.Unitize();
                if (direction.DotProduct(currentState.Direction) >= visibilityCosineFactor)
                {
                    target = targetCell;
                    break;
                }
            }
            return(target);
        }