//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));
        }
        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) }
            });
        }
        //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)));
        }
Example #4
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 #5
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));
        }
        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) },
            });
        }
        //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);
        }
        //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);
        }