//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); }
//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)); }
//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)); }
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) } }); }