Exemple #1
0
        //returns the highest and lowest point along with indices from a pointlist
        internal static Dictionary <string, object> ReturnHighestAndLowestPointofBBox(Polygon2d poly)
        {
            Range2d range = PolygonUtility.GetRang2DFromBBox(ReadData.FromPointsGetBoundingPoly(poly.Points));
            double  minX = range.Xrange.Min;
            double  maxX = range.Xrange.Max;
            double  minY = range.Yrange.Min;
            double  maxY = range.Yrange.Max;
            Point2d lowPt = new Point2d(minX, minY), hipt = new Point2d(maxX, maxY);


            return(new Dictionary <string, object>
            {
                { "LowerPoint", (lowPt) },
                { "HigherPoint", (hipt) },
            });
        }
Exemple #2
0
        internal static Dictionary <string, object> ExtLinesAndOffsetsFromBBox(Polygon2d poly, double patientRoomDepth = 16, double recompute = 5)
        {
            if (!ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            Polygon2d     polyReg       = new Polygon2d(poly.Points);
            List <Line2d> allSplitLines = new List <Line2d>();
            Polygon2d     polyBBox      = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polyReg.Points));

            allSplitLines = polyBBox.Lines;
            List <double> splitLineLength = new List <double>();

            for (int i = 0; i < allSplitLines.Count; i++)
            {
                splitLineLength.Add(allSplitLines[i].Length);
            }
            List <int> sortedIndices = BasicUtility.Quicksort(splitLineLength);

            if (sortedIndices != null)
            {
                sortedIndices.Reverse();
            }

            List <Line2d>  offsetLines   = new List <Line2d>();
            List <Point2d> midPtsOffsets = new List <Point2d>();

            for (int i = 0; i < allSplitLines.Count; i++)
            {
                offsetLines.Add(LineUtility.Offset(allSplitLines[i], patientRoomDepth));
                midPtsOffsets.Add(LineUtility.NudgeLineMidPt(allSplitLines[i], poly, patientRoomDepth));
            }

            List <Line2d> offsetSortedLines = new List <Line2d>();

            for (int i = 0; i < offsetLines.Count; i++)
            {
                offsetSortedLines.Add(offsetLines[sortedIndices[i]]);
            }
            return(new Dictionary <string, object>
            {
                { "SplittableLines", (allSplitLines) },
                { "OffsetLines", (offsetSortedLines) },
                { "SortedIndices", (sortedIndices) },
                { "OffsetMidPts", (midPtsOffsets) }
            });
        }
        //subdivide a given poly into smaller parts till acceptable width is met, returns list of polydept grids and list of polys to compute circulation
        public static List <List <Polygon2d> > SplitRecursivelyToSubdividePoly(List <Polygon2d> polyList, double acceptableWidth = 10, double circulationFreq = 10, double ratio = 0.5, bool tag = false)
        {
            if (!ValidateObject.CheckPolyList(polyList))
            {
                return(null);
            }

            int count = 0;
            Queue <Polygon2d>        polyQueue = new Queue <Polygon2d>();
            List <List <Polygon2d> > polyAllReturn = new List <List <Polygon2d> >();
            List <Polygon2d>         polyBrokenList = new List <Polygon2d>(), polyCirculationList = new List <Polygon2d>();
            double totalArea = 0; // cirFac = Math.Ceiling(acceptableWidth/ circulationFreq);
            double cirFac = circulationFreq;

            for (int i = 0; i < polyList.Count; i++)
            {
                totalArea += PolygonUtility.AreaPolygon(polyList[i]);
                polyQueue.Enqueue(polyList[i]);
            }
            Random rand = new Random();
            double targetArea = totalArea / cirFac;

            while (polyQueue.Count > 0)
            {
                Polygon2d currentPoly = polyQueue.Dequeue();
                Dictionary <string, object> splitObj = SplitByRatio(currentPoly, ratio, 0);
                if (tag)
                {
                    ratio = BasicUtility.RandomBetweenNumbers(rand, 0.7, 0.35);
                }
                if (splitObj == null)
                {
                    continue;
                }
                List <Polygon2d> polySplitList = (List <Polygon2d>)splitObj["PolyAfterSplit"];
                if (ValidateObject.CheckPolyList(polySplitList) && polySplitList.Count > 1)
                {
                    polySplitList = PolygonUtility.SmoothPolygonList(polySplitList, 2);
                    Polygon2d bbox1 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[0].Points));
                    Polygon2d bbox2 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[1].Points));
                    if (!ValidateObject.CheckPoly(bbox1) || !ValidateObject.CheckPoly(bbox2))
                    {
                        continue;
                    }

                    if (PolygonUtility.AreaPolygon(polySplitList[0]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[0]);
                    }
                    if (PolygonUtility.AreaPolygon(polySplitList[1]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[1]);
                    }

                    if (bbox1.Lines[0].Length < acceptableWidth || bbox1.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[0]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[0]);
                    }
                    if (bbox2.Lines[0].Length < acceptableWidth || bbox2.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[1]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[1]);
                    }
                }
                if (ValidateObject.CheckPolyList(polySplitList) && polySplitList.Count < 2)
                {
                    Polygon2d bbox1 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[0].Points));
                    if (!ValidateObject.CheckPoly(bbox1))
                    {
                        continue;
                    }
                    if (bbox1.Lines[0].Length < acceptableWidth || bbox1.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[0]);
                    }
                    if (PolygonUtility.AreaPolygon(polySplitList[0]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[0]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[0]);
                    }
                }
                count += 1;
            }

            for (int i = 0; i < polyQueue.Count; i++)
            {
                polyBrokenList.Add(polyQueue.Dequeue());
            }
            polyAllReturn.Add(polyBrokenList);
            polyAllReturn.Add(polyCirculationList);
            return(polyAllReturn);
        }
        //Builds Dept Topology Matrix , finds all the shared edges between dept polys, and updates department polygon2d's.
        /// <summary>
        /// Builds the department topology matrix internally and finds circulation network lines between department polygon2d's.
        /// </summary>
        /// <param name="deptData">DeptData Object</param>
        /// <param name="leftOverPoly">Polygon2d not assigned to any department.</param>
        /// <param name="limit">Maximum distance allowed to be considered as a neighbor of a department.</param>
        /// <returns name="CirculationNetwork">List of line2d geometry representing circulation network between department polygon2d's.</returns>
        /// <search>
        /// Department Circulation Network, Shared Edges between departments
        /// </search>

        internal static List <Line2d> RemoveNetworkRedundancy(List <Line2d> networkLines, double circulationFrequency = 10)
        {
            if (networkLines == null)
            {
                return(null);
            }
            circulationFrequency = 1 - circulationFrequency;
            Polygon2d     bBox = ReadData.GetBoundingBoxfromLines(networkLines);
            List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(bBox.Points);// horizontal span 1st, then vertical span
            List <Line2d> horizLines = new List <Line2d>(), vertLines = new List <Line2d>();

            for (int i = 0; i < networkLines.Count; i++)
            {
                if (ValidateObject.CheckLineOrient(networkLines[i]) == 0)
                {
                    horizLines.Add(networkLines[i]);
                }
                else if (ValidateObject.CheckLineOrient(networkLines[i]) == 1)
                {
                    vertLines.Add(networkLines[i]);
                }
            }
            List <Line2d> selectedHorizLines = new List <Line2d>(), selectedVertLines = new List <Line2d>();

            for (int i = 0; i < horizLines.Count; i++)
            {
                double thresDistance = circulationFrequency * spans[0];
                int    a = i, b = i + 1;
                if (i == horizLines.Count - 1)
                {
                    b = 0;
                }
                Point2d midA = LineUtility.LineMidPoint(horizLines[a]), midB = LineUtility.LineMidPoint(horizLines[b]);
                double  xDist = Math.Abs(midA.Y - midB.Y);
                if (xDist > thresDistance)
                {
                    selectedHorizLines.Add(horizLines[a]);
                }
            }

            for (int i = 0; i < vertLines.Count; i++)
            {
                double thresDistance = circulationFrequency * spans[1];
                int    a = i, b = i + 1;
                if (i == vertLines.Count - 1)
                {
                    b = 0;
                }
                Point2d midA = LineUtility.LineMidPoint(vertLines[a]), midB = LineUtility.LineMidPoint(vertLines[b]);
                double  yDist = Math.Abs(midA.X - midB.X);
                if (yDist > thresDistance)
                {
                    selectedVertLines.Add(vertLines[a]);
                }
            }
            List <Line2d> reducedLines = new List <Line2d>();

            reducedLines.AddRange(selectedHorizLines);
            reducedLines.AddRange(selectedVertLines);

            return(reducedLines);
        }