Exemple #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);
        }
Exemple #2
0
        //make polygon2d on grids
        public static Polygon2d MakeSquarePolygon2dFromCenterSide(Point2d centerPt, double side)
        {
            List <Point>   ptList   = MakeSquarePointsFromCenterSide(centerPt, side);
            List <Point2d> pt2dList = new List <Point2d>();

            for (int i = 0; i < ptList.Count; i++)
            {
                pt2dList.Add(new Point2d(ptList[i].X, ptList[i].Y));
            }
            return(Polygon2d.ByPoints(pt2dList));
        }
Exemple #3
0
        //checks if two points are within a certain threshold region
        internal static bool CheckPointsWithinRange(Point2d ptA, Point2d ptB, double threshold = 2)
        {
            List <Point2d> squarePts = new List <Point2d>();

            squarePts.Add(Point2d.ByCoordinates(ptA.X + threshold, ptA.Y - threshold)); //LR
            squarePts.Add(Point2d.ByCoordinates(ptA.X + threshold, ptA.Y + threshold)); //UR
            squarePts.Add(Point2d.ByCoordinates(ptA.X - threshold, ptA.Y + threshold)); //UL
            squarePts.Add(Point2d.ByCoordinates(ptA.X - threshold, ptA.Y - threshold)); //LLl
            Polygon2d squarePoly = Polygon2d.ByPoints(squarePts);

            return(GraphicsUtility.PointInsidePolygonTest(squarePoly, ptB));
        }
Exemple #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) }
            });
        }
        //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);
        }
        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) }
            });
        }