示例#1
0
        //gets list of polygon2ds and find the most closest polygon2d to the center , to place the central stn
        internal static Dictionary <string, object> MakeCentralStation(List <Polygon2d> polygonsList, Point2d centerPt)
        {
            if (polygonsList == null || polygonsList.Count == 0)
            {
                return(null);
            }
            if (polygonsList.Count < 2)
            {
                return(new Dictionary <string, object>
                {
                    { "PolyCentral", (polygonsList) },
                    { "IndexInPatientPoly", (0) }
                });
            }
            List <Polygon2d> newPolyLists = new List <Polygon2d>();
            List <double>    distanceList = new List <double>();
            double           minArea = 100, ratio = 0.5, dis = 0;; int dir = 0;
            List <int>       indices     = PolygonUtility.SortPolygonsFromAPoint(polygonsList, centerPt);
            Polygon2d        polyToPlace = polygonsList[indices[0]];
            double           area        = PolygonUtility.AreaPolygon(polyToPlace);

            if (area > minArea)
            {
                List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(polyToPlace.Points);
                if (spans[0] > spans[1])
                {
                    dir = 1;
                    dis = spans[0] / 2;
                }
                else
                {
                    dir = 0;
                    dis = spans[1] / 2;
                }
                Random ran = new Random();
                //Dictionary<string, object> splittedPoly = BasicSplitPolyIntoTwo(polyToPlace, ratio, dir);
                //Dictionary<string, object> splittedPoly = SplitByDistanceFromPoint(polyToPlace, dis, dir);
                Dictionary <string, object> splittedPoly     = SplitObject.SplitByDistance(polyToPlace, ran, dis, dir);
                List <Polygon2d>            polyReturnedList = (List <Polygon2d>)splittedPoly["PolyAfterSplit"];
                if (!ValidateObject.CheckPolyList(polyReturnedList))
                {
                    return(null);
                }
                List <int> ind = PolygonUtility.SortPolygonsFromAPoint(polyReturnedList, centerPt);
                newPolyLists.Add(polyReturnedList[ind[0]]);
                newPolyLists.Add(polyReturnedList[ind[1]]);
            }
            else
            {
                newPolyLists.Add(polyToPlace);
            }
            return(new Dictionary <string, object>
            {
                { "PolyCentral", (newPolyLists) },
                { "IndexInPatientPoly", (indices[0]) }
            });
        }
示例#2
0
        //checks a polygon2d to have min Area and min dimensions
        internal static bool CheckPolyDimension(Polygon2d poly, double minArea = 6, double side = 2)
        {
            if (!CheckPoly(poly))
            {
                return(false);
            }
            if (PolygonUtility.AreaPolygon(poly) < minArea)
            {
                return(false);
            }
            List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points);

            if (spans[0] < side)
            {
                return(false);
            }
            if (spans[1] < side)
            {
                return(false);
            }
            return(true);
        }
示例#3
0
        //checsk the aspect ratio of polygons
        internal static bool CheckPolyAspectRatio(Polygon2d poly, double minDimensionAllowed = 5)
        {
            if (!CheckPoly(poly))
            {
                return(false);
            }

            List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points);

            if (spans.Count > 1)
            {
                if (spans[0] < minDimensionAllowed || spans[1] < minDimensionAllowed)
                {
                    return(false);
                }
                double aspectRatio = spans[0] / spans[1];
                if (aspectRatio < 1)
                {
                    aspectRatio = 1 / aspectRatio;
                }
                if (aspectRatio > 5)
                {
                    return(false);
                }
                if (aspectRatio > 1.5)
                {
                    double areaShouldBe = spans[0] * spans[1];
                    double areaPoly     = PolygonUtility.AreaPolygon(poly);
                    if (areaPoly / areaShouldBe < 0.9)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        //gets a poly and recursively splits it till acceptabledimension is met and makes a polyorganized list
        internal static void MakePolysOfProportion(Polygon2d poly, List <Polygon2d> polyOrganizedList,
                                                   List <Polygon2d> polycoverList, double acceptableWidth, double targetArea)
        {
            BuildLayout.RECURSE += 1;
            List <double> spanListXY = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points);
            double        spanX = spanListXY[0], spanY = spanListXY[1];
            double        aspRatio = spanX / spanY;
            double        lowRange = 0.3, highRange = 2;
            double        maxValue = 0.70, minValue = 0.35;
            double        threshDistanceX = acceptableWidth;
            double        threshDistanceY = acceptableWidth;
            Random        ran             = new Random();
            bool          square          = true;
            double        div;

            div = BasicUtility.RandomBetweenNumbers(BuildLayout.RANGENERATE, maxValue, minValue);
            if (spanX > threshDistanceX && spanY > threshDistanceY)
            {
                square = false;
            }
            else
            {
                if (aspRatio > lowRange && aspRatio < highRange)
                {
                    square = false;
                }
                else
                {
                    square = true;
                }
            }
            if (square)
            {
                polyOrganizedList.Add(poly);
            }
            else
            {
                Dictionary <string, object> splitResult;
                //poly is rectangle so split it into two and add
                if (spanX > spanY)
                {
                    double dis = spanY * div;
                    int    dir = 1;
                    //splitResult = BasicSplitPolyIntoTwo(poly, 0.5, dir);
                    splitResult = SplitObject.SplitByDistance(poly, ran, dis, dir, BuildLayout.SPACING2);
                    //splitResult = SplitByDistanceFromPoint(poly, dis, dir);
                }
                else
                {
                    double dis = spanX * div;
                    int    dir = 0;
                    //splitResult = BasicSplitPolyIntoTwo(poly, 0.5, dir);
                    splitResult = SplitObject.SplitByDistance(poly, ran, dis, dir, BuildLayout.SPACING2);
                    //splitResult = SplitByDistanceFromPoint(poly, dis, dir);
                }

                List <Polygon2d> polyAfterSplit = (List <Polygon2d>)splitResult["PolyAfterSplit"];
                if (ValidateObject.CheckPolyList(polyAfterSplit))
                {
                    double areaPolA = PolygonUtility.AreaPolygon(polyAfterSplit[0]);
                    double areaPolB = PolygonUtility.AreaPolygon(polyAfterSplit[1]);
                    if (areaPolA > targetArea)
                    {
                        polycoverList.Add(polyAfterSplit[0]);
                    }
                    if (areaPolB > targetArea)
                    {
                        polycoverList.Add(polyAfterSplit[1]);
                    }

                    List <double> spanA = PolygonUtility.GetSpansXYFromPolygon2d(polyAfterSplit[0].Points);
                    List <double> spanB = PolygonUtility.GetSpansXYFromPolygon2d(polyAfterSplit[1].Points);
                    //Trace.WriteLine("RECURSE is : " + RECURSE);
                    if (BuildLayout.RECURSE < 1500)
                    {
                        if ((spanA[0] > 0 && spanA[1] > 0) || (spanB[0] > 0 && spanB[1] > 0))
                        {
                            if (spanA[0] > acceptableWidth && spanA[1] > acceptableWidth)
                            {
                                MakePolysOfProportion(polyAfterSplit[0], polyOrganizedList, polycoverList, acceptableWidth, targetArea);
                            }
                            else
                            {
                                polyOrganizedList.Add(polyAfterSplit[0]);
                                double areaPoly = PolygonUtility.AreaPolygon(polyAfterSplit[0]);
                            }
                            //end of 1st if
                            if (spanB[0] > acceptableWidth && spanB[1] > acceptableWidth)
                            {
                                MakePolysOfProportion(polyAfterSplit[1], polyOrganizedList, polycoverList, acceptableWidth, targetArea);
                            }
                            else
                            {
                                polyOrganizedList.Add(polyAfterSplit[1]);
                            }
                            //end of 2nd if
                        }
                        else
                        {
                            polyOrganizedList.Add(polyAfterSplit[0]);
                            polyOrganizedList.Add(polyAfterSplit[1]);
                        }
                    }
                } // end of if loop , checkingpolylists
            }
        }         // end of function
        public static Dictionary <string, object> SplitByRatio(Polygon2d polyOutline, double ratio = 0.5, int dir = 0)
        {
            if (polyOutline == null)
            {
                return(null);
            }
            if (polyOutline != null && polyOutline.Points == null)
            {
                return(null);
            }

            double         extents = 5000;
            double         minimumLength = 2, minWidth = 10, aspectRatio = 0, eps = 0.1;
            List <Point2d> polyOrig = polyOutline.Points;
            List <Point2d> poly = PolygonUtility.SmoothPolygon(polyOrig, BuildLayout.SPACING);
            List <double>  spans = PolygonUtility.GetSpansXYFromPolygon2d(poly);
            double         horizontalSpan = spans[0], verticalSpan = spans[1];
            Point2d        polyCenter = PolygonUtility.CentroidOfPoly(Polygon2d.ByPoints(poly));

            if (horizontalSpan < minimumLength || verticalSpan < minimumLength)
            {
                return(null);
            }

            if (horizontalSpan > verticalSpan)
            {
                dir = 1; aspectRatio = horizontalSpan / verticalSpan;
            }
            else
            {
                dir = 0; aspectRatio = verticalSpan / horizontalSpan;
            }

            // adjust ratio
            if (ratio < 0.15)
            {
                ratio = ratio + eps;
            }
            if (ratio > 0.85)
            {
                ratio = ratio - eps;
            }

            if (horizontalSpan < minWidth || verticalSpan < minWidth)
            {
                ratio = 0.5;
            }
            Line2d splitLine = new Line2d(polyCenter, extents, dir);
            double shift     = ratio - 0.5;

            if (dir == 0)
            {
                splitLine = LineUtility.Move(splitLine, 0, shift * verticalSpan);
            }
            else
            {
                splitLine = LineUtility.Move(splitLine, shift * horizontalSpan, 0);
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, BuildLayout.SPACING);
            List <Point2d>   intersectedPoints             = (List <Point2d>)intersectionReturn["IntersectedPoints"];
            List <Polygon2d> splittedPoly = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) },
                { "IntersectedPoints", (intersectedPoints) }
            });
        }
        //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);
        }