Beispiel #1
0
        //sorts a list of points form a polyline
        public static List <Point2d> SortPoints(List <Point2d> pointList)
        {
            if (!ValidateObject.CheckPointList(pointList))
            {
                return(null);
            }
            Point2d       cen     = PolygonUtility.CentroidOfPoly(Polygon2d.ByPoints(pointList));
            Vector2d      vecX    = new Vector2d(0, 100);
            List <double> angList = new List <double>();

            int[] indList = new int[pointList.Count];
            for (int i = 0; i < pointList.Count; i++)
            {
                Vector2d CenterToPt = new Vector2d(cen, pointList[i]);
                double   dotValue   = vecX.Dot(CenterToPt);
                double   angValue   = Math.Atan2(CenterToPt.Y - vecX.Y, CenterToPt.X - vecX.X);
                angList.Add(angValue);
                indList[i] = i;
            }
            List <int> newIndexList = new List <int>();

            newIndexList = BasicUtility.SortIndex(angList);
            List <Point2d> sortedPointList = new List <Point2d>();

            for (int i = 0; i < pointList.Count; i++)
            {
                sortedPointList.Add(pointList[newIndexList[i]]);
            }
            return(sortedPointList);
        }
Beispiel #2
0
        //check if a given polygon2d has any of its longer edges aligned with any edge of the containerpolygon2d
        internal static bool CheckLineGetsExternalWall(Line2d lineA, Polygon2d containerPoly)
        {
            bool check = false;

            if (!ValidateObject.CheckPoly(containerPoly))
            {
                return(check);
            }
            Polygon2d containerPolyReg = new Polygon2d(containerPoly.Points);

            for (int i = 0; i < containerPoly.Points.Count; i++)
            {
                int a = i, b = i + 1;
                if (i == containerPolyReg.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d lineB = Line2d.ByStartPointEndPoint(containerPolyReg.Points[a], containerPolyReg.Points[b]);
                check = GraphicsUtility.LineAdjacencyCheck(lineA, lineB);
                if (check)
                {
                    break;
                }
            }
            return(check);
        }
        //checks if two lines are collinear or not
        public static bool LineAdjacencyCheck(Line2d lineA, Line2d lineB, double eps = 0)
        {
            Point2d pA = lineA.StartPoint, qA = lineA.EndPoint;
            Point2d pB = lineB.StartPoint, qB = lineB.EndPoint;

            Vector2d vecA = new Vector2d(pA, qA), vecB = new Vector2d(pB, qB);
            double   crossMag = vecA.Cross(vecB);

            if (crossMag != 0)
            {
                return(false);
            }

            bool checkA1 = ValidateObject.CheckOnSegment(lineB, pA), checkA2 = ValidateObject.CheckOnSegment(lineB, qA);
            bool checkB1 = ValidateObject.CheckOnSegment(lineA, pB), checkB2 = ValidateObject.CheckOnSegment(lineA, qB);

            if (checkA1 || checkA2)
            {
                return(true);
            }
            if (checkB1 || checkB2)
            {
                return(true);
            }
            return(false);
        }
        public static Dictionary <string, object> SplitByDistance(Polygon2d polyOutline, Random ran, double distance = 10, int dir = 0, double spacing = 0)
        {
            if (!ValidateObject.CheckPoly(polyOutline))
            {
                return(null);
            }
            double         extents = 5000, spacingProvided;
            List <Point2d> polyOrig = polyOutline.Points;

            if (spacing == 0)
            {
                spacingProvided = BuildLayout.SPACING;
            }
            else
            {
                spacingProvided = spacing;
            }

            List <Point2d> poly = PolygonUtility.SmoothPolygon(polyOrig, spacingProvided);

            if (!ValidateObject.CheckPointList(poly))
            {
                return(null);
            }
            Dictionary <int, object> obj = PointUtility.PointSelector(ran, poly);
            Point2d pt        = (Point2d)obj[0];
            int     orient    = (int)obj[1];
            Line2d  splitLine = new Line2d(pt, extents, dir);

            // push this line right or left or up or down based on ratio
            if (dir == 0)
            {
                splitLine = LineUtility.Move(splitLine, 0, orient * distance);
            }
            else
            {
                splitLine = LineUtility.Move(splitLine, orient * distance, 0);
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, spacingProvided);
            List <Point2d>   intersectedPoints             = (List <Point2d>)intersectionReturn["IntersectedPoints"];
            List <Polygon2d> splittedPoly = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];
            List <Point2d>   ptA = (List <Point2d>)intersectionReturn["PointASide"];
            List <Point2d>   ptB = (List <Point2d>)intersectionReturn["PointBSide"];
            Polygon2d        polyA = new Polygon2d(ptA, 0), polyB = new Polygon2d(ptB, 0);

            //List<Polygon2d> splittedPoly = new List<Polygon2d>();
            //splittedPoly.Add(polyA); splittedPoly.Add(polyB);
            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) },
                { "IntersectedPoints", (intersectedPoints) },
                { "PointASide", (ptA) },
                { "PointBSide", (ptB) }
            });
        }
Beispiel #5
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]) }
            });
        }
Beispiel #6
0
        //check if a given polygon2d has any of its longer edges aligned with any edge of the containerpolygon2d
        internal static bool CheckPolyGetsExternalWall(Polygon2d poly, Polygon2d containerPoly, double shortEdgeDist = 16, bool tag = true)
        {
            bool check = false;

            if (!ValidateObject.CheckPoly(poly))
            {
                return(check);
            }
            Polygon2d polyReg = new Polygon2d(null);

            //make given polys reduce number of points
            if (tag)
            {
                polyReg = new Polygon2d(poly.Points);
            }
            else
            {
                polyReg = poly;
            }
            Polygon2d containerPolyReg = new Polygon2d(containerPoly.Points);

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                int    a = i, b = i + 1;
                double eps = 0;
                if (i == polyReg.Points.Count - 1)
                {
                    b = 0;
                }
                double        distance    = PointUtility.DistanceBetweenPoints(polyReg.Points[a], polyReg.Points[b]);
                List <double> spansSorted = PolygonUtility.GetPolySpan(containerPolyReg);
                if (distance <= spansSorted[0] * 0.75)
                {
                    continue;
                }
                Line2d lineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], polyReg.Points[b]);
                for (int j = 0; j < containerPolyReg.Points.Count; j++)
                {
                    int c = j, d = j + 1;
                    if (j == containerPolyReg.Points.Count - 1)
                    {
                        d = 0;
                    }
                    Line2d lineB = Line2d.ByStartPointEndPoint(containerPolyReg.Points[c], containerPolyReg.Points[d]);
                    check = GraphicsUtility.LineAdjacencyCheck(lineA, lineB, eps);
                    if (check)
                    {
                        break;
                    }
                }
                if (check)
                {
                    break;
                }
            }
            return(check);
        }
        //offsets an input line by a given distance inside a poly
        public static Line2d OffsetLineInsidePoly(Line2d lineInp, Polygon2d poly, double distance)
        {
            if (lineInp == null || !ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            Point2d  ptStart = OffsetLinePointInsidePoly(lineInp, lineInp.StartPoint, poly, distance);
            Vector2d vec     = new Vector2d(lineInp.StartPoint, ptStart);
            Point2d  ptEnd   = VectorUtility.VectorAddToPoint(lineInp.EndPoint, vec);

            return(new Line2d(ptStart, ptEnd));
        }
        //offsets an input point by a given distance inside a poly
        internal static Point2d OffsetLinePointInsidePoly(Line2d lineInp, Point2d testPoint, Polygon2d poly, double distance)
        {
            if (lineInp == null || !ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            int dir = DirectionForPointInPoly(lineInp, poly, distance);

            if (dir == 0)
            {
                return(null);
            }
            return(OffsetLinePoint(lineInp, testPoint, dir * distance));
        }
Beispiel #9
0
        //returns the points on the required side of a given line, 0 is left or up, 1 is right or down
        internal static List <Point2d> PointOnSide(Line2d line, List <Point2d> ptList, int side)
        {
            if (line == null || !ValidateObject.CheckPointList(ptList))
            {
                return(null);
            }
            List <Point2d> selectedPts = new List <Point2d>();

            if (side == 0)
            {
            }

            return(selectedPts);
        }
        //offsets an input point by a given distance
        internal static Point2d OffsetLinePoint(Line2d lineInp, Point2d testPoint, double distance)
        {
            double newX1 = 0, newY1 = 0;

            if (ValidateObject.CheckLineOrient(lineInp) == 0) // horizontal line
            {
                newX1 = testPoint.X;
                newY1 = testPoint.Y + distance;
            }
            else // vertical line
            {
                newX1 = testPoint.X + distance;
                newY1 = testPoint.Y;
            }
            return(new Point2d(newX1, newY1));
        }
Beispiel #11
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) }
            });
        }
        public static Dictionary <string, object> SplitByLine(Polygon2d polyOutline, Line2d inputLine, double distance = 5)
        {
            if (!ValidateObject.CheckPoly(polyOutline))
            {
                return(null);
            }
            List <Point2d> polyOrig   = polyOutline.Points;
            List <Point2d> poly       = PolygonUtility.SmoothPolygon(polyOrig, BuildLayout.SPACING);
            Line2d         splitLine  = new Line2d(inputLine);
            Point2d        centerPoly = PointUtility.CentroidInPointLists(poly);
            bool           checkSide  = ValidateObject.CheckPointSide(splitLine, centerPoly);
            int            orient     = ValidateObject.CheckLineOrient(splitLine);

            if (orient == 0)
            {
                if (!checkSide)
                {
                    splitLine = LineUtility.Move(splitLine, 0, -1 * distance);
                }
                else
                {
                    splitLine = LineUtility.Move(splitLine, 0, 1 * distance);
                }
            }
            else
            {
                if (checkSide)
                {
                    splitLine = LineUtility.Move(splitLine, -1 * distance, 0);
                }
                else
                {
                    splitLine = LineUtility.Move(splitLine, 1 * distance, 0);
                }
            }

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

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) }
            });
        }
        }         // end of function

        //makes intersections and returns the two polygon2ds after intersection
        internal static Dictionary <string, object> MakeIntersections(List <Point2d> poly, Line2d splitLine, double space = 0)
        {
            List <Point2d> intersectedPoints = GraphicsUtility.LinePolygonIntersection(poly, splitLine);
            //List<Point2d> intersectedPoints = TestGraphicsUtility.LinePolygonIntersectionIndex(poly, splitLine);
            // find all points on poly which are to the left or to the right of the line
            List <int> pIndexA = new List <int>();
            List <int> pIndexB = new List <int>();

            for (int i = 0; i < poly.Count; i++)
            {
                bool check = ValidateObject.CheckPointSide(splitLine, poly[i]);
                if (check)
                {
                    pIndexA.Add(i);
                }
                else
                {
                    pIndexB.Add(i);
                }
            }
            //organize the points to make closed poly
            List <Point2d> sortedA = PointUtility.DoSortClockwise(poly, intersectedPoints, pIndexA);
            List <Point2d> sortedB = PointUtility.DoSortClockwise(poly, intersectedPoints, pIndexB);

            /*List<Polygon2d> splittedPoly = new List<Polygon2d>();
             * if (space == 0) splittedPoly = new List<Polygon2d> { new Polygon2d(sortedA, 0), new Polygon2d(sortedB, 0) };
             * else
             * {
             *   sortedA = PolygonUtility.SmoothPolygon(new Polygon2d(sortedA,0).Points, space);
             *   sortedB = PolygonUtility.SmoothPolygon(new Polygon2d(sortedB,0).Points, space);
             *   splittedPoly = new List<Polygon2d> { new Polygon2d(sortedA, 0), new Polygon2d(sortedB, 0) };
             * }
             */
            List <Polygon2d> splittedPoly = new List <Polygon2d> {
                new Polygon2d(sortedA, 0), new Polygon2d(sortedB, 0)
            };

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "IntersectedPoints", (intersectedPoints) },
                { "PointASide", (sortedA) },
                { "PointBSide", (sortedB) }
            });
        }
Beispiel #14
0
        //################################################################################################################
        //this class stores methods realted to GraphicsUtility class which needs to be tested further for reliability
        //################################################################################################################

        // checks if two lines are collinear - not using
        internal static bool CheckLineCollinear(Line2d lineA, Line2d lineB)
        {
            Point2d p1 = lineA.StartPoint;
            Point2d p2 = lineA.EndPoint;
            Point2d q1 = lineB.StartPoint;
            Point2d q2 = lineB.EndPoint;

            // Find the four orientations needed for general and special cases
            int o1 = GraphicsUtility.Orientation(p1, q1, p2);
            int o2 = GraphicsUtility.Orientation(p1, q1, q2);
            int o3 = GraphicsUtility.Orientation(p2, q2, p1);
            int o4 = GraphicsUtility.Orientation(p2, q2, q1);

            // General case
            if (o1 != o2 && o3 != o4)
            {
                return(false);
            }
            // p1, q1 and p2 are colinear and p2 lies on segment p1q1
            if (o1 == 0 && ValidateObject.CheckOnSegment(p1, p2, q1))
            {
                return(true);
            }

            // p1, q1 and p2 are colinear and q2 lies on segment p1q1
            if (o2 == 0 && ValidateObject.CheckOnSegment(p1, q2, q1))
            {
                return(true);
            }

            // p2, q2 and p1 are colinear and p1 lies on segment p2q2
            if (o3 == 0 && ValidateObject.CheckOnSegment(p2, p1, q2))
            {
                return(true);
            }

            // p2, q2 and q1 are colinear and q1 lies on segment p2q2
            if (o4 == 0 && ValidateObject.CheckOnSegment(p2, q1, q2))
            {
                return(true);
            }
            return(false); // Doesn't fall in any of the above cases
        }
        //offsets an input line by a given distance
        internal static int DirectionForPointInPoly(Line2d lineInp, Polygon2d poly, double distance)
        {
            if (lineInp == null || !ValidateObject.CheckPoly(poly))
            {
                return(0);
            }
            Point2d midPt = LineMidPoint(lineInp);
            Point2d pt1   = OffsetLinePoint(lineInp, midPt, distance);
            Point2d pt2   = OffsetLinePoint(lineInp, midPt, -1 * distance);

            if (GraphicsUtility.PointInsidePolygonTest(poly, pt1))
            {
                return(1);
            }
            else
            {
                return(-1);
            }
        }
        internal static Polygon2d AddpointToPoly(Polygon2d poly, int lineId = 0)
        {
            if (!ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            List <Point2d> ptList = new List <Point2d>();

            for (int i = 0; i < poly.Points.Count; i++)
            {
                if (i == lineId)
                {
                    Line2d line = poly.Lines[lineId];
                }

                ptList.Add(poly.Points[i]);
            }
            return(null);
        }
Beispiel #17
0
        //returns the point having lowest x,y value from a list using now
        internal static int LowestPointFromList(List <Point2d> ptList)
        {
            if (!ValidateObject.CheckPointList(ptList))
            {
                return(-1);
            }
            Point2d lowestPoint = ptList[0];
            int     size        = ptList.Count;
            int     index       = 0;

            for (int i = 0; i < size; i++)
            {
                if ((lowestPoint.X > ptList[i].X) || (lowestPoint.X == ptList[i].X && lowestPoint.Y > ptList[i].Y))
                {
                    lowestPoint = ptList[i];
                    index       = i;
                }
            }
            return(index);
        }
        //checks if a point is inside a polygon or not
        public static bool PointInsidePolygonTest(Polygon2d poly, Point2d testPoint)
        {
            if (!ValidateObject.CheckPoly(poly) || testPoint == null)
            {
                return(false);
            }
            bool           check         = false;
            List <Point2d> pointsPolygon = poly.Points;
            int            numPolyPts    = pointsPolygon.Count;

            for (int i = 0, j = numPolyPts - 1; i < numPolyPts; j = i++)
            {
                if (((pointsPolygon[i].Y > testPoint.Y) != (pointsPolygon[j].Y > testPoint.Y)) &&
                    (testPoint.X < (pointsPolygon[j].X - pointsPolygon[i].X) * (testPoint.Y - pointsPolygon[i].Y) / (pointsPolygon[j].Y - pointsPolygon[i].Y) + pointsPolygon[i].X))
                {
                    check = !check;
                }
            }
            return(check);
        }
Beispiel #19
0
        //returns the point having highest x,y value from a list - using now
        internal static int ReturnHighestPointFromList(List <Point2d> ptList)
        {
            if (!ValidateObject.CheckPointList(ptList))
            {
                return(-1);
            }
            Point2d highestPoint = ptList[0];
            int     size         = ptList.Count;
            int     index        = 0;

            for (int i = 0; i < size; i++)
            {
                if ((highestPoint.Y < ptList[i].Y) || (highestPoint.Y == ptList[i].Y && highestPoint.X > ptList[i].X))
                {
                    highestPoint = ptList[i];
                    index        = i;
                }
            }
            return(index);
        }
Beispiel #20
0
 //sort point array for Grahams scan algo to find convex hull
 internal static void SortedPoint2dListForGrahamScan(ref List <Point2d> ptList, int size)
 {
     for (int i = 1; i < size; ++i)
     {
         for (int j = i + 1; j < size; ++j)
         {
             int order = ValidateObject.CheckPointOrder(ptList[0], ptList[i], ptList[j]);
             // collinear
             if (order == 0)
             {
                 if (DistanceBetweenPoints(ptList[0], ptList[0]) <= DistanceBetweenPoints(ptList[0], ptList[j]))
                 {
                     ChangePlaces(ref ptList, i, j);
                 }
             }
             else if (order == 1)
             {
                 ChangePlaces(ref ptList, i, j);
             }
         }
     }
 }
        //removes duplicate lines from a list, based on the lines from another list
        internal static List <Line2d> RemoveDuplicateLinesBasedOnMidPt(List <Line2d> lineListOrig, List <Line2d> otherLineList)
        {
            List <Line2d> lineEditedList = new List <Line2d>();

            for (int i = 0; i < lineListOrig.Count; i++)
            {
                lineEditedList.Add(lineListOrig[i]);
            }
            List <bool> duplicateTagList = new List <bool>();

            for (int i = 0; i < lineListOrig.Count; i++)
            {
                bool duplicate = false;
                for (int j = 0; j < otherLineList.Count; j++)
                {
                    Point2d midPtOrig  = LineUtility.LineMidPoint(lineListOrig[i]);
                    Point2d midPtOther = LineUtility.LineMidPoint(otherLineList[j]);
                    //if (midPtOrig.Compare(midPtOther)) { duplicate = true; break; }
                    if (ValidateObject.CheckPointsWithinRange(midPtOrig, midPtOther, 4))
                    {
                        duplicate = true; break;
                    }
                }
                duplicateTagList.Add(duplicate);
            }
            int count = 0;

            for (int i = 0; i < duplicateTagList.Count; i++)
            {
                if (duplicateTagList[i])
                {
                    lineEditedList.RemoveAt(i - count);
                    count += 1;
                }
            }
            return(lineEditedList);
        }
        //extends both  ends of a line
        public static Line2d ExtendLine(Line2d line, double extend = 0)
        {
            if (extend == 0)
            {
                extend = 10000;
            }
            double startPtX = 0, startPtY = 0, endPtX = 0, endPtY = 0;

            if (ValidateObject.CheckLineOrient(line) == 1)
            {
                startPtX = line.StartPoint.X;
                startPtY = line.StartPoint.Y - extend;
                endPtX   = line.EndPoint.X;
                endPtY   = line.EndPoint.Y + extend;
            }
            else
            {
                startPtX = line.StartPoint.X - extend;
                startPtY = line.StartPoint.Y;
                endPtX   = line.EndPoint.X + extend;
                endPtY   = line.EndPoint.Y;
            }
            return(new Line2d(new Point2d(startPtX, startPtY), new Point2d(endPtX, endPtY)));
        }
        public static Dictionary <string, object> SplitByOffsetFromLine(Polygon2d polyOutline, int lineId, double distance = 10, double minDist = 0)
        {
            if (!ValidateObject.CheckPoly(polyOutline))
            {
                return(null);
            }
            Polygon2d poly = new Polygon2d(polyOutline.Points, 0);

            List <Point2d> pointForBlock = new List <Point2d>();
            List <Point2d> polyPtsCopy   = poly.Points.Select(pt => new Point2d(pt.X, pt.Y)).ToList();//deep copy

            for (int i = 0; i < poly.Points.Count; i++)
            {
                int a = i, b = i + 1, c = i - 1;
                if (c < 0)
                {
                    c = poly.Points.Count - 1;
                }
                if (i == poly.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d prevLine = poly.Lines[c];
                Line2d currLine = poly.Lines[a];
                Line2d nextLine = poly.Lines[b];
                if (i == lineId)
                {
                    Line2d line = new Line2d(poly.Points[a], poly.Points[b]);
                    if (line.Length < minDist)
                    {
                        continue;
                    }
                    Line2d offsetLine = LineUtility.OffsetLineInsidePoly(line, poly, distance);
                    pointForBlock.Add(poly.Points[a]);
                    pointForBlock.Add(poly.Points[b]);
                    pointForBlock.Add(offsetLine.EndPoint);
                    pointForBlock.Add(offsetLine.StartPoint);
                    int orientPrev = ValidateObject.CheckLineOrient(prevLine);
                    int orientCurr = ValidateObject.CheckLineOrient(currLine);
                    int orientNext = ValidateObject.CheckLineOrient(nextLine);

                    // case 1
                    if (orientPrev == orientCurr && orientCurr == orientNext)
                    {
                        polyPtsCopy.Insert(b, offsetLine.EndPoint);
                        polyPtsCopy.Insert(b, offsetLine.StartPoint);
                    }

                    // case 2
                    if (orientPrev != orientCurr && orientCurr == orientNext)
                    {
                        polyPtsCopy[a] = offsetLine.StartPoint;
                        polyPtsCopy.Insert(b, offsetLine.EndPoint);
                    }

                    // case 3
                    if (orientPrev == orientCurr && orientCurr != orientNext)
                    {
                        polyPtsCopy.Insert(b, offsetLine.StartPoint);
                        polyPtsCopy[b + 1] = offsetLine.EndPoint;
                    }

                    // case 4
                    if (orientPrev != orientCurr && orientCurr != orientNext)
                    {
                        polyPtsCopy[a] = offsetLine.StartPoint;
                        polyPtsCopy[b] = offsetLine.EndPoint;
                    }
                }
            }
            Polygon2d polySplit = new Polygon2d(pointForBlock, 0);
            Polygon2d leftPoly  = new Polygon2d(polyPtsCopy, 0); //poly.Points

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (polySplit) },
                { "LeftOverPoly", (leftPoly) },
            });
        }
Beispiel #24
0
        internal static Dictionary <string, object> FindOuterLinesAndOffsets(Polygon2d poly, double patientRoomDepth = 16, double extension = 8000, double recompute = 5)
        {
            if (!ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            Polygon2d      polyReg = new Polygon2d(poly.Points);
            List <Line2d>  hLines = new List <Line2d>();
            List <Line2d>  vLines = new List <Line2d>();
            List <Point2d> hMidPt = new List <Point2d>();
            List <Point2d> vMidPt = new List <Point2d>();
            List <Line2d>  nonOrthoLines = new List <Line2d>();
            int            countOrtho = 0, countNonOrtho = 0;

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                int a = i, b = i + 1;
                if (i == polyReg.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d line     = new Line2d(polyReg.Points[a], polyReg.Points[b]);
                int    lineType = ValidateObject.CheckLineOrient(line);
                if (lineType > -1)
                {
                    if (lineType == 0)
                    {
                        Line2d extendedLine = LineUtility.ExtendLine(line, extension);
                        hLines.Add(extendedLine);
                        hMidPt.Add(LineUtility.LineMidPoint(line));
                    }
                    if (lineType == 1)
                    {
                        Line2d extendedLine = LineUtility.ExtendLine(line, extension);
                        vLines.Add(extendedLine);
                        vMidPt.Add(LineUtility.LineMidPoint(line));
                    }
                    countOrtho += 1;
                }
                else
                {
                    countNonOrtho += 1;
                    nonOrthoLines.Add(line);
                }
            }
            List <Line2d> selectedHLines = new List <Line2d>();
            List <Line2d> selectedVLines = new List <Line2d>();
            int           hIndLow        = CodeToBeTested.ReturnLowestPointFromList(hMidPt);
            int           hIndHigh       = CodeToBeTested.ReturnHighestPointFromList(hMidPt);
            int           vIndLow        = PointUtility.LowestPointFromList(vMidPt);
            int           vIndHigh       = PointUtility.HighestPointFromList(vMidPt);

            if (hIndLow > -1)
            {
                selectedHLines.Add(hLines[hIndLow]);
            }
            if (hIndHigh > -1)
            {
                selectedHLines.Add(hLines[hIndHigh]);
            }
            if (vIndLow > -1)
            {
                selectedVLines.Add(vLines[vIndLow]);
            }
            if (vIndHigh > -1)
            {
                selectedVLines.Add(vLines[vIndHigh]);
            }

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

            allSplitLines.AddRange(selectedHLines);
            allSplitLines.AddRange(selectedVLines);
            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) },
                { "NonOrthoLines", (nonOrthoLines) }
            });
        }
Beispiel #25
0
        internal static Dictionary <string, object> AddPointToFitPoly(Polygon2d poly, Polygon2d containerPoly, double distance = 16, double area = 0, double thresDistance = 10, double recompute = 5)
        {
            if (!ValidateObject.CheckPoly(poly))
            {
                return(null);
            }
            if (distance < 1)
            {
                return(null);
            }

            Dictionary <string, object> lineOffsetCheckObj = ValidateObject.CheckLinesOffsetInPoly(poly, containerPoly, distance);
            List <int>             indicesFalse            = (List <int>)lineOffsetCheckObj["IndicesFalse"];
            List <List <Point2d> > pointsFalse             = (List <List <Point2d> >)lineOffsetCheckObj["PointsOutside"];
            List <Point2d>         probPointList           = new List <Point2d>();
            List <Point2d>         polyNewPoints           = new List <Point2d>();
            List <Line2d>          falseLines = new List <Line2d>();
            Point2d ptNewEnd = new Point2d(0, 0);
            Point2d otherPt = new Point2d(0, 0);
            Point2d probPt = new Point2d(0, 0);
            Line2d  line = new Line2d(ptNewEnd, otherPt);
            int     count = 0, maxTry = 50;
            double  ratio = 0, increment = .25;
            bool    added = false, checkOffPtNew = false;

            for (int i = 0; i < poly.Points.Count; i++)
            {
                int a = i, b = i + 1;
                if (i == poly.Points.Count - 1)
                {
                    b = 0;
                }
                polyNewPoints.Add(poly.Points[a]);
                if (indicesFalse[i] > -1)
                {
                    falseLines.Add(poly.Lines[i]);
                }
                if (poly.Lines[i].Length > thresDistance &&
                    indicesFalse[i] > -1 && pointsFalse[i] != null && pointsFalse[i].Count == 1 && !added && LayoutUtility.CheckLineGetsExternalWall(poly.Lines[i], containerPoly))
                {
                    probPointList.AddRange(pointsFalse[i]);
                    probPt = pointsFalse[i][0];
                    line   = poly.Lines[i];
                    Point2d midPt = LineUtility.LineMidPoint(line);
                    if (line.StartPoint.Compare(probPt))
                    {
                        otherPt = line.EndPoint;
                    }
                    else
                    {
                        otherPt = line.StartPoint;
                    }
                    Vector2d vecToOther = new Vector2d(probPt, otherPt);
                    while (!checkOffPtNew && count < maxTry && ratio < 0.9)
                    {
                        ratio   += increment;
                        ptNewEnd = VectorUtility.VectorAddToPoint(probPt, vecToOther, ratio);
                        Point2d offPtNew = LineUtility.OffsetLinePointInsidePoly(line, ptNewEnd, poly, distance);
                        checkOffPtNew = GraphicsUtility.PointInsidePolygonTest(poly, offPtNew);
                        count        += 1;
                    }
                    polyNewPoints.Add(ptNewEnd);
                    added = true;
                }
            }
            Polygon2d polyAdded = new Polygon2d(polyNewPoints, 0);

            return(new Dictionary <string, object>
            {
                { "PolyAddedPts", (polyAdded) },
                { "ProblemPoint", (probPt) },
                { "IsAdded", (added) },
                { "PointAdded", (ptNewEnd) },
                { "Trials", (count) },
                { "FinalRatio", (ratio) },
                { "ProblemLine", (line) },
                { "ProblemPtsList", (probPointList) },
                { "FalseLineList", (falseLines) }
            });
        }
        public static Dictionary <string, object> MakeProgCirculationPolys(List <Line2d> circulationNetwork, List <Polygon2d> polyProgList, double circulationWidth = 8, double circulationFrequency = 0.5, int designSeed = 10)
        {
            if (!ValidateObject.CheckPolyList(polyProgList))
            {
                return(null);
            }
            if (circulationNetwork == null || circulationNetwork.Count == 0)
            {
                return(null);
            }
            List <Line2d> flatLineList    = new List <Line2d>();
            List <bool>   IsDuplicateList = new List <bool>();

            polyProgList = PolygonUtility.SmoothPolygonList(polyProgList, 5);

            //flatten all the polys in each depts to make it one list
            List <Polygon2d> circulationPolyList = new List <Polygon2d>();
            List <Polygon2d> updatedProgPolyList = new List <Polygon2d>();
            List <int>       deptIdList          = new List <int>();
            double           allowedCircRatio    = 4;
            List <double>    areaProgPolyList    = new List <double>();

            for (int i = 0; i < polyProgList.Count; i++)
            {
                areaProgPolyList.Add(PolygonUtility.AreaPolygon(polyProgList[i]));
            }

            double maxArea = areaProgPolyList.Max();

            areaProgPolyList.Sort();
            int    value      = (int)(areaProgPolyList.Count / 3);
            double areaThresh = areaProgPolyList[value];
            Random ran        = new Random(designSeed);

            for (int i = 0; i < circulationNetwork.Count; i++)
            {
                Line2d splitter   = circulationNetwork[i];
                double someNumber = BasicUtility.RandomBetweenNumbers(ran, 1, 0);
                if (someNumber > circulationFrequency)
                {
                    continue;
                }
                for (int j = 0; j < polyProgList.Count; j++)
                {
                    Polygon2d progPoly = polyProgList[j];
                    double    areaPoly = PolygonUtility.AreaPolygon(progPoly);

                    Point2d midPt       = LineUtility.LineMidPoint(splitter);
                    Point2d nudgedMidPt = LineUtility.NudgeLineMidPt(splitter, progPoly, 0.5);
                    bool    checkInside = GraphicsUtility.PointInsidePolygonTest(progPoly, nudgedMidPt);

                    if (checkInside)
                    {
                        Dictionary <string, object> splitResult    = SplitObject.SplitByLine(progPoly, splitter, circulationWidth);
                        List <Polygon2d>            polyAfterSplit = (List <Polygon2d>)(splitResult["PolyAfterSplit"]);
                        if (ValidateObject.CheckPolyList(polyAfterSplit))
                        {
                            double areaA = PolygonUtility.AreaPolygon(polyAfterSplit[0]), areaB = PolygonUtility.AreaPolygon(polyAfterSplit[1]);
                            if (areaA < areaB)
                            {
                                if (polyAfterSplit[0].Points != null)
                                {
                                    if (ValidateObject.CheckPolyBBox(polyAfterSplit[0], allowedCircRatio))
                                    {
                                        circulationPolyList.Add(polyAfterSplit[0]);
                                    }
                                }
                                updatedProgPolyList.Add(polyAfterSplit[1]);
                            }
                            else
                            {
                                if (polyAfterSplit[1].Points != null)
                                {
                                    if (ValidateObject.CheckPolyBBox(polyAfterSplit[1], allowedCircRatio))
                                    {
                                        circulationPolyList.Add(polyAfterSplit[1]);
                                    }
                                }
                                updatedProgPolyList.Add(polyAfterSplit[0]);
                            }
                        } // end of if loop checking polylist
                    }     // end of check inside
                }         // end of for loop j
            }             // end of for loop i

            return(new Dictionary <string, object>
            {
                { "ProgCirculationPoly", (circulationPolyList) }
            });
        }
Beispiel #27
0
        //make the given poly all points orthonogonal to each other
        internal static Polygon2d MakePolyPointsOrtho(Polygon2d poly)
        {
            Polygon2d      polyReg        = new Polygon2d(poly.Points);
            List <Point2d> ptForOrthoPoly = new List <Point2d>();

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                Point2d pt = Point2d.ByCoordinates(polyReg.Points[i].X, polyReg.Points[i].Y);
                ptForOrthoPoly.Add(pt);
            }

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                int    a = i, b = i + 1;
                double eps = 50;
                if (i == polyReg.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d line = new Line2d(polyReg.Points[a], polyReg.Points[b]);
                if (ValidateObject.CheckLineOrient(line) == -1)
                {
                    //double diffX = Math.Abs(line.StartPoint.X - line.EndPoint.X);
                    //double diffY = Math.Abs(line.StartPoint.Y - line.EndPoint.Y);
                    Point2d cenPoly  = PolygonUtility.CentroidOfPoly(polyReg);
                    Point2d ptEndA   = Point2d.ByCoordinates(polyReg.Points[a].X + eps, polyReg.Points[a].Y);
                    Line2d  refLineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], ptEndA);

                    Point2d ptEndB   = Point2d.ByCoordinates(polyReg.Points[b].X + eps, polyReg.Points[b].Y);
                    Line2d  refLineB = Line2d.ByStartPointEndPoint(polyReg.Points[b], ptEndB);

                    Point2d projectedPtA = GraphicsUtility.ProjectedPointOnLine(refLineB, polyReg.Points[a]);
                    Point2d projectedPtB = GraphicsUtility.ProjectedPointOnLine(refLineA, polyReg.Points[b]);

                    Vector2d vecA       = new Vector2d(projectedPtA, cenPoly);
                    Vector2d vecB       = new Vector2d(projectedPtB, cenPoly);
                    double   vecALength = vecA.Length;
                    double   vecBLength = vecB.Length;
                    if (vecALength > vecBLength)
                    {
                        //ptForOrthoPoly[i] = projectedPtA;
                        ptForOrthoPoly.Insert(b, projectedPtB);
                    }
                    else
                    {
                        //ptForOrthoPoly[i] = projectedPtB;
                        ptForOrthoPoly.Insert(b, projectedPtA);
                    }

                    /*
                     * if (diffX > diffY)
                     * {
                     *  Point2d ptEndA = Point2d.ByCoordinates(polyReg.Points[a].X, polyReg.Points[a].Y + eps);
                     *  Line2d refLineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], ptEndA);
                     *  refLineA = LineUtility.extend(refLineA);
                     *
                     *  Point2d ptEndB = Point2d.ByCoordinates(polyReg.Points[b].X, polyReg.Points[b].Y + eps);
                     *  Line2d refLineB = Line2d.ByStartPointEndPoint(polyReg.Points[b], ptEndB);
                     *  refLineB = LineUtility.extend(refLineB);
                     *
                     *  Point2d projectedPtA = GraphicsUtility.ProjectedPointOnLine(refLineB, polyReg.Points[a]);
                     *  Point2d projectedPtB = GraphicsUtility.ProjectedPointOnLine(refLineA, polyReg.Points[b]);
                     *
                     *  Vector2d vecA = new Vector2d(projectedPtA, cenPoly);
                     *  Vector2d vecB = new Vector2d(projectedPtB, cenPoly);
                     *  double vecALength = vecA.Length;
                     *  double vecBLength = vecB.Length;
                     *  if(vecALength < vecBLength)
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtA;
                     *      ptForOrthoPoly.Insert(b, projectedPtB);
                     *  }
                     *  else
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtB;
                     *      ptForOrthoPoly.Insert(b, projectedPtA);
                     *  }
                     * }
                     * else
                     * {
                     *
                     *  Point2d ptEndA = Point2d.ByCoordinates(polyReg.Points[a].X + eps, polyReg.Points[a].Y);
                     *  Line2d refLineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], ptEndA);
                     *  refLineA = LineUtility.extend(refLineA);
                     *
                     *  Point2d ptEndB = Point2d.ByCoordinates(polyReg.Points[b].X + eps, polyReg.Points[b].Y);
                     *  Line2d refLineB = Line2d.ByStartPointEndPoint(polyReg.Points[b], ptEndB);
                     *  refLineB = LineUtility.extend(refLineB);
                     *
                     *  Point2d projectedPtA = GraphicsUtility.ProjectedPointOnLine(refLineB, polyReg.Points[a]);
                     *  Point2d projectedPtB = GraphicsUtility.ProjectedPointOnLine(refLineA, polyReg.Points[b]);
                     *
                     *  Vector2d vecA = new Vector2d(projectedPtA, cenPoly);
                     *  Vector2d vecB = new Vector2d(projectedPtB, cenPoly);
                     *  double vecALength = vecA.Length;
                     *  double vecBLength = vecB.Length;
                     *  if (vecALength < vecBLength)
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtA;
                     *      ptForOrthoPoly.Insert(b, projectedPtB);
                     *  }
                     *  else
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtB;
                     *      ptForOrthoPoly.Insert(b, projectedPtB);
                     *  }
                     * }
                     */
                }
            }
            return(new Polygon2d(ptForOrthoPoly));
        }
        //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);
        }
        //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> FindDeptCirculationNetwork(List <DeptData> deptData, Polygon2d leftOverPoly = null, bool noExternalWall = false, double circulationFrequency = 0.75)
        {
            if (deptData == null || deptData.Count == 0)
            {
                return(null);
            }
            double                limit = 0;
            List <Polygon2d>      polygonsAllDeptList = new List <Polygon2d>();
            List <DeptData>       deptDataAllDeptList = new List <DeptData>();
            List <List <string> > deptNamesNeighbors  = new List <List <string> >();
            List <List <Line2d> > lineCollection      = new List <List <Line2d> >();

            //make flattened list of all dept data and dept polys
            for (int i = 0; i < deptData.Count; i++)
            {
                List <Polygon2d> polyList = deptData[i].PolyAssignedToDept;
                if (!ValidateObject.CheckPolyList(polyList))
                {
                    continue;
                }
                for (int j = 0; j < polyList.Count; j++)
                {
                    polygonsAllDeptList.Add(polyList[j]);
                    deptDataAllDeptList.Add(deptData[i]);
                }
            }
            if (leftOverPoly != null)
            {
                polygonsAllDeptList.Add(leftOverPoly);
            }
            //else Trace.WriteLine("leftover poly found null, so not added");
            List <Line2d> networkLine = new List <Line2d>();

            for (int i = 0; i < polygonsAllDeptList.Count; i++)
            {
                Polygon2d polyA = polygonsAllDeptList[i];
                for (int j = i + 1; j < polygonsAllDeptList.Count; j++)
                {
                    Polygon2d polyB = polygonsAllDeptList[j];
                    Dictionary <string, object> checkNeighbor = PolygonUtility.FindPolyAdjacentEdge(polyA, polyB, limit);
                    if (checkNeighbor != null)
                    {
                        if ((bool)checkNeighbor["Neighbour"] == true)
                        {
                            networkLine.Add((Line2d)checkNeighbor["SharedEdge"]);
                        }
                    }
                }
            }

            // if externalWalls not necessary
            List <Line2d>    extraLines  = new List <Line2d>();
            List <Polygon2d> polyKeyList = new List <Polygon2d>();

            if (noExternalWall)
            {
                polyKeyList = deptData[0].PolyAssignedToDept;
                for (int i = 0; i < polyKeyList.Count; i++)
                {
                    Polygon2d polyA = polyKeyList[i];
                    for (int j = i + 1; j < polyKeyList.Count; j++)
                    {
                        Polygon2d polyB = polyKeyList[j];
                        Dictionary <string, object> checkNeighbor = PolygonUtility.FindPolyAdjacentEdgeEdit(polyA, polyB, 0.05);
                        if (checkNeighbor != null)
                        {
                            if ((bool)checkNeighbor["Neighbour"] == true)
                            {
                                networkLine.Add((Line2d)checkNeighbor["SharedEdge"]);
                                extraLines.Add((Line2d)checkNeighbor["SharedEdge"]);
                            }
                        }
                    }
                }
            }
            List <Line2d> cleanNetworkLines = LineUtility.RemoveDuplicateLines(networkLine);

            // extend the lines found
            for (int i = 0; i < cleanNetworkLines.Count; i++)
            {
                cleanNetworkLines[i] = LineUtility.ExtendLine(cleanNetworkLines[i], 2000);
            }

            cleanNetworkLines = RemoveNetworkRedundancy(cleanNetworkLines, circulationFrequency);

            //return cleanNetworkLines;
            return(new Dictionary <string, object>
            {
                { "CirculationNetworkLines", (cleanNetworkLines) }
            });
        }