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) }
            });
        }
        public static Dictionary <string, object> SplitByDistanceFromPoint(Polygon2d polyOutline, double distance = 10, int dir = 0, double space = 0)
        {
            if (polyOutline == null || polyOutline.Points == null || polyOutline.Points.Count == 0)
            {
                return(null);
            }
            if (space == 0)
            {
                space = BuildLayout.SPACING2;
            }
            double         extents     = 5000;
            int            threshValue = 50;
            List <Point2d> polyOrig    = polyOutline.Points;
            List <Point2d> poly        = new List <Point2d>();

            if (polyOrig.Count > threshValue)
            {
                poly = polyOrig;
            }
            else
            {
                poly = PolygonUtility.SmoothPolygon(polyOrig, space);
            }

            if (poly == null || poly.Count == 0)
            {
                return(null);
            }
            int     lowInd    = PointUtility.LowestPointFromList(poly);
            Point2d lowPt     = poly[lowInd];
            Line2d  splitLine = new Line2d(lowPt, extents, dir);

            if (dir == 0)
            {
                splitLine = LineUtility.Move(splitLine, 0, 1 * distance);
            }
            else
            {
                splitLine = LineUtility.Move(splitLine, 1 * distance, 0);
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, space);
            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"];

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) },
                { "IntersectedPoints", (intersectedPoints) },
                { "PointASide", (ptA) },
                { "PointBSide", (ptB) }
            });
        }
        internal static Polygon2d GetBoundingBoxfromLines(List <Line2d> lineList)
        {
            if (lineList == null)
            {
                return(null);
            }
            List <Point2d> ptList = new List <Point2d>();

            for (int i = 0; i < lineList.Count; i++)
            {
                ptList.Add(LineUtility.LineMidPoint(lineList[i]));
            }
            return(new Polygon2d(FromPointsGetBoundingPoly(ptList)));
        }
Example #4
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) }
            });
        }
        //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);
        }
        //removes duplicate lines from a list, based on line adjacency check
        internal static List <Line2d> RemoveDuplicateLinesBasedOnAdjacency(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 (GraphicsUtility.LineAdjacencyCheck(lineListOrig[i], otherLineList[j]))
                    {
                        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);
        }
        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) },
            });
        }
        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) }
            });
        }
        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) }
            });
        }
Example #11
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> MakeDeptCirculationPolys(List <DeptData> deptData, List <List <Line2d> > circulationNetwork, double circulationWidth = 8)
        {
            if (deptData == null || deptData.Count == 0 || circulationNetwork == null || circulationNetwork.Count == 0)
            {
                return(null);
            }
            List <Line2d>    cleanLineList       = LineUtility.FlattenLine2dList(circulationNetwork);
            List <Polygon2d> allDeptPolyList     = new List <Polygon2d>();
            List <Polygon2d> circulationPolyList = new List <Polygon2d>();
            List <Polygon2d> updatedDeptPolyList = new List <Polygon2d>();
            List <int>       deptIdList          = new List <int>();

            for (int i = 0; i < deptData.Count; i++)
            {
                List <Polygon2d> deptPolyList = deptData[i].PolyAssignedToDept;
                if (!ValidateObject.CheckPolyList(deptPolyList))
                {
                    continue;
                }
                for (int j = 0; j < deptPolyList.Count; j++)
                {
                    deptIdList.Add(i);
                    allDeptPolyList.Add(deptPolyList[j]);
                }
            }

            for (int i = 0; i < cleanLineList.Count; i++)
            {
                Line2d splitter = cleanLineList[i];
                for (int j = 0; j < allDeptPolyList.Count; j++)
                {
                    Polygon2d deptPoly    = allDeptPolyList[j];
                    Point2d   midPt       = LineUtility.LineMidPoint(splitter);
                    Point2d   nudgedMidPt = LineUtility.NudgeLineMidPt(splitter, deptPoly, 0.5);
                    if (GraphicsUtility.PointInsidePolygonTest(deptPoly, nudgedMidPt))
                    {
                        Dictionary <string, object> splitResult    = SplitObject.SplitByLine(deptPoly, splitter, circulationWidth);
                        List <Polygon2d>            polyAfterSplit = (List <Polygon2d>)(splitResult["PolyAfterSplit"]);
                        if (ValidateObject.CheckPolyList(polyAfterSplit))
                        {
                            double areaA = PolygonUtility.AreaPolygon(polyAfterSplit[0]);
                            double areaB = PolygonUtility.AreaPolygon(polyAfterSplit[1]);
                            if (areaA < areaB)
                            {
                                circulationPolyList.Add(polyAfterSplit[0]);
                                updatedDeptPolyList.Add(polyAfterSplit[1]);
                            }
                            else
                            {
                                circulationPolyList.Add(polyAfterSplit[1]);
                                updatedDeptPolyList.Add(polyAfterSplit[0]);
                            }
                        }
                    } // end of check inside
                }     // end of for loop j
            }         // end of for loop i

            List <List <Polygon2d> > deptPolyBranchedInList = new List <List <Polygon2d> >();
            List <int> distinctIdList = deptIdList.Distinct().ToList();

            for (int i = 0; i < distinctIdList.Count; i++)
            {
                List <Polygon2d> polyForDeptBranch = new List <Polygon2d>();
                for (int j = 0; j < deptIdList.Count; j++)
                {
                    if (deptIdList[j] == i)
                    {
                        if (j < updatedDeptPolyList.Count)
                        {
                            polyForDeptBranch.Add(updatedDeptPolyList[j]);
                        }
                    }
                }
                deptPolyBranchedInList.Add(polyForDeptBranch);
            }
            return(new Dictionary <string, object>
            {
                { "DeptCirculationPoly", (circulationPolyList) },
                { "UpdatedDeptPolys", (deptPolyBranchedInList) }
            });
        }
        //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);
        }
Example #14
0
        internal static Dictionary <string, object> PolygonPolygonCommonEdgeDict(Polygon2d poly, Polygon2d other)
        {
            bool check = false;

            if (poly == null || other == null)
            {
                return(null);
            }

            double    eps      = 200;
            Polygon2d polyReg  = new Polygon2d(poly.Points);
            Polygon2d otherReg = new Polygon2d(other.Points);
            Dictionary <string, object> UpdatedCenters = ComputePolyCentersAlign(polyReg, otherReg);

            Point2d centerPoly  = (Point2d)UpdatedCenters["CenterPolyA"];
            Point2d centerOther = (Point2d)UpdatedCenters["CenterPolyB"];

            polyReg  = (Polygon2d)UpdatedCenters["PolyA"];
            otherReg = (Polygon2d)UpdatedCenters["PolyB"];
            //make vectors
            Vector2d centerToCen  = new Vector2d(centerPoly, centerOther);
            Vector2d centerToCenX = new Vector2d(centerToCen.X, 0);
            Vector2d centerToCenY = new Vector2d(0, centerToCen.Y);
            //make centerLine
            Line2d   centerLine = new Line2d(centerPoly, centerOther);
            Vector2d keyVec;

            if (centerToCenX.Length > centerToCenY.Length)
            {
                keyVec = new Vector2d(centerToCenX.X, centerToCenX.Y);
            }
            else
            {
                keyVec = new Vector2d(centerToCenY.X, centerToCenY.Y);
            }
            //check line poly intersection between centertocen vector and each polys
            Line2d lineInPolyReg  = CodeToBeTested.LinePolygonIntersectionReturnLine(polyReg.Points, centerLine, centerOther);
            Line2d lineInOtherReg = CodeToBeTested.LinePolygonIntersectionReturnLine(otherReg.Points, centerLine, centerPoly);

            //find distance d1 and d2 from two centers to linepolyintersection line
            Point2d projectedPtOnPolyReg  = GraphicsUtility.ProjectedPointOnLine(lineInPolyReg, centerPoly);
            Point2d projectedPtOnOtherReg = GraphicsUtility.ProjectedPointOnLine(lineInOtherReg, centerOther);

            double dist1 = PointUtility.DistanceBetweenPoints(centerPoly, projectedPtOnPolyReg);
            double dist2 = PointUtility.DistanceBetweenPoints(centerOther, projectedPtOnOtherReg);

            double totalDistance = 2 * (dist1 + dist2);
            Line2d lineMoved     = new Line2d(lineInPolyReg.StartPoint, lineInPolyReg.EndPoint);

            lineMoved = LineUtility.Move(lineMoved, centerPoly);
            Point2d projectedPt = GraphicsUtility.ProjectedPointOnLine(lineMoved, centerOther);
            double  distance    = PointUtility.DistanceBetweenPoints(projectedPt, centerOther);

            bool isNeighbour = false;

            if (totalDistance - eps < distance && distance < totalDistance + eps)
            {
                isNeighbour = true;
            }
            else
            {
                isNeighbour = false;
            }

            return(new Dictionary <string, object>
            {
                { "Neighbour", (isNeighbour) },
                { "SharedEdgeA", (lineInPolyReg) },
                { "SharedEdgeB", (lineInOtherReg) },
                { "LineMoved", (lineMoved) },
                { "CenterToCenterLine", (centerLine) },
                { "CenterPolyPoint", (centerPoly) },
                { "CenterPolyOtherPoint", (centerOther) },
            });
        }
        //removes duplicates lines from a list of lines
        public static List <Line2d> CleanLines(List <Line2d> lineList)
        {
            List <Line2d> cleanList  = new List <Line2d>();
            List <bool>   taggedList = new List <bool>();

            for (int i = 0; i < lineList.Count; i++)
            {
                Line2d lin = new Line2d(lineList[i].StartPoint, lineList[i].EndPoint);
                cleanList.Add(lin);
                taggedList.Add(false);
            }

            for (int i = 0; i < lineList.Count; i++)
            {
                double eps   = 1;
                Line2d lineA = lineList[i];
                for (int j = i + 1; j < lineList.Count; j++)
                {
                    Line2d lineB   = lineList[j];
                    int    orientA = ValidateObject.CheckLineOrient(lineA);
                    int    orientB = ValidateObject.CheckLineOrient(lineB);
                    if (orientA != orientB)
                    {
                        continue;
                    }
                    else
                    {
                        Point2d midA = LineUtility.LineMidPoint(lineA);
                        Point2d midB = LineUtility.LineMidPoint(lineB);
                        if (orientA == 0)
                        {
                            //lines are horizontal
                            if ((midA.Y - eps < midB.Y && midB.Y < midA.Y + eps) ||
                                (midB.Y - eps < midA.Y && midA.Y < midB.Y + eps))
                            {
                                // lines are duplicate check length, whichever has longer length will be added to list
                                double lenA = lineA.Length;
                                double lenB = lineB.Length;
                                if (lenA > lenB)
                                {
                                    taggedList[i] = true;
                                }
                                else
                                {
                                    taggedList[j] = true;
                                }
                            }// end of if statement
                        }
                        else
                        {
                            //lines are vertical
                            if ((midA.X - eps < midB.X && midB.X < midA.X + eps) ||
                                (midB.X - eps < midA.X && midA.X < midB.X + eps))
                            {
                                double lenA = lineA.Length;
                                double lenB = lineB.Length;
                                if (lenA > lenB)
                                {
                                    cleanList.Add(lineA);
                                }
                                else
                                {
                                    cleanList.Add(lineB);
                                }
                            }// end of if statement
                        }
                    }
                }
            }
            return(cleanList);
        }
        public static Dictionary <string, object> FindProgCirculationNetwork(List <DeptData> deptData, Polygon2d buildingOutline, List <Polygon2d> leftOverPoly = null)
        {
            if (!ValidateObject.CheckPoly(buildingOutline))
            {
                return(null);
            }
            if (deptData == null)
            {
                return(null);
            }
            List <Polygon2d>      polygonsAllProgList = new List <Polygon2d>();
            List <DeptData>       deptDataAllDeptList = new List <DeptData>();
            List <List <Line2d> > lineCollection      = new List <List <Line2d> >();

            for (int i = 0; i < deptData.Count; i++)
            {
                if ((deptData[i].DepartmentType.IndexOf(BuildLayout.KPU.ToLower()) != -1 ||
                     deptData[i].DepartmentType.IndexOf(BuildLayout.KPU.ToUpper()) != -1))
                {
                    continue;                                                                      // dont add for KPU
                }
                if (deptData[i].PolyAssignedToDept == null)
                {
                    continue;
                }
                polygonsAllProgList.AddRange(deptData[i].PolyAssignedToDept);
            }
            if (leftOverPoly != null)
            {
                polygonsAllProgList.AddRange(leftOverPoly);
            }
            for (int i = 0; i < polygonsAllProgList.Count; i++)
            {
                polygonsAllProgList[i] = new Polygon2d(polygonsAllProgList[i].Points);
            }

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

            for (int i = 0; i < polygonsAllProgList.Count; i++)
            {
                Polygon2d poly1 = polygonsAllProgList[i];
                for (int j = i + 1; j < polygonsAllProgList.Count; j++)
                {
                    Polygon2d poly2 = polygonsAllProgList[j];
                    Dictionary <string, object> checkNeighbor = PolygonUtility.FindPolyAdjacentEdge(poly1, poly2);
                    if (checkNeighbor != null)
                    {
                        if ((bool)checkNeighbor["Neighbour"] == true)
                        {
                            networkLine.Add((Line2d)checkNeighbor["SharedEdge"]);
                        }
                    }
                }
            }
            List <Line2d> cleanNetworkLines = LineUtility.RemoveDuplicateLines(networkLine);

            cleanNetworkLines = GraphicsUtility.RemoveDuplicateslinesWithPoly(buildingOutline, cleanNetworkLines);
            List <List <string> > deptNeighborNames = new List <List <string> >();

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

            for (int i = 0; i < cleanNetworkLines.Count; i++)
            {
                bool checkOrtho = ValidateObject.CheckLineOrthogonal(cleanNetworkLines[i]);
                if (checkOrtho == true)
                {
                    onlyOrthoLineList.Add(cleanNetworkLines[i]);
                }
            }
            return(new Dictionary <string, object>
            {
                { "CirculationNetwork", (onlyOrthoLineList) },
                { "PolygonsForAllPrograms", (polygonsAllProgList) }
            });
        }
        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) }
            });
        }
Example #18
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) }
            });
        }
Example #19
0
        internal static Dictionary <string, object> CheckLinesOffsetInPoly(Polygon2d poly, Polygon2d containerPoly, double distance = 10, bool tag = false)
        {
            if (!CheckPoly(poly))
            {
                return(null);
            }
            Polygon2d              oPoly             = PolygonUtility.OffsetPoly(poly, 0.2);
            List <bool>            offsetAble        = new List <bool>();
            List <List <Point2d> > pointsOutsideList = new List <List <Point2d> >();
            List <Line2d>          linesNotOffset    = new List <Line2d>();
            List <int>             indicesFalse      = new List <int>();

            for (int i = 0; i < poly.Points.Count; i++)
            {
                bool offsetAllow = false;
                int  a = i, b = i + 1;
                if (i == poly.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d  line         = poly.Lines[i];
                Point2d offStartPt   = LineUtility.OffsetLinePointInsidePoly(line, line.StartPoint, oPoly, distance);
                Point2d offEndPt     = LineUtility.OffsetLinePointInsidePoly(line, line.EndPoint, oPoly, distance);
                bool    checkStartPt = GraphicsUtility.PointInsidePolygonTest(oPoly, offStartPt);
                bool    checkEndPt   = GraphicsUtility.PointInsidePolygonTest(oPoly, offEndPt);
                bool    checkExtEdge = LayoutUtility.CheckLineGetsExternalWall(line, containerPoly);
                if (tag)
                {
                    checkExtEdge = true;
                }
                List <Point2d> pointsDefault = new List <Point2d>();
                if (checkStartPt && checkEndPt && checkExtEdge)
                {
                    offsetAllow = true;
                    indicesFalse.Add(-1);
                    pointsDefault.Add(null);
                }
                else
                {
                    if (!checkStartPt)
                    {
                        pointsDefault.Add(line.StartPoint);
                    }
                    if (!checkEndPt)
                    {
                        pointsDefault.Add(line.EndPoint);
                    }
                    linesNotOffset.Add(line);
                    indicesFalse.Add(i);
                    offsetAllow = false;
                }
                pointsOutsideList.Add(pointsDefault);
                offsetAble.Add(offsetAllow);
            }
            return(new Dictionary <string, object>
            {
                { "LinesFalse", (linesNotOffset) },
                { "Offsetables", (offsetAble) },
                { "IndicesFalse", (indicesFalse) },
                { "PointsOutside", (pointsOutsideList) }
            });
        }