internal static Dictionary <string, object> ComputePolyCentersAlign(Polygon2d polyA, Polygon2d polyB) { //compute orig centers Point2d centerPolyA = PointUtility.CentroidInPointLists(polyA.Points); Point2d centerPolyB = PointUtility.CentroidInPointLists(polyB.Points); Point2d staticPoint, movingPoint; Polygon2d staticPoly, movingPoly; double areaPolyA = PolygonUtility.AreaPolygon(polyA); double areaPolyB = PolygonUtility.AreaPolygon(polyB); if (areaPolyA > areaPolyB) { staticPoint = centerPolyB; staticPoly = polyB; movingPoint = centerPolyA; movingPoly = polyA; } else { staticPoint = centerPolyA; staticPoly = polyA; movingPoint = centerPolyB; movingPoly = polyB; } //shift the other points Point2d movingPoint1 = new Point2d(staticPoint.X, movingPoint.Y); Point2d movingPoint2 = new Point2d(movingPoint.X, staticPoint.Y); bool IsMovingPoint1 = GraphicsUtility.PointInsidePolygonTest(movingPoly, movingPoint1); bool IsMovingPoint2 = GraphicsUtility.PointInsidePolygonTest(movingPoly, movingPoint2); if (IsMovingPoint1) { movingPoint = movingPoint1; } else if (IsMovingPoint2) { movingPoint = movingPoint2; } else { staticPoint = centerPolyA; staticPoly = polyA; movingPoint = movingPoint1; movingPoly = polyB; } return(new Dictionary <string, object> { { "CenterPolyA", (staticPoint) }, { "CenterPolyB", (movingPoint) }, { "PolyA", (staticPoly) }, { "PolyB", (movingPoly) } }); }
//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)); }
//offsets an input line by a given distance internal static int DirectionForPointInPoly(Line2d lineInp, Polygon2d poly, double distance) { if (lineInp == null || !ValidateObject.CheckPoly(poly)) { return(0); } Point2d midPt = LineMidPoint(lineInp); Point2d pt1 = OffsetLinePoint(lineInp, midPt, distance); Point2d pt2 = OffsetLinePoint(lineInp, midPt, -1 * distance); if (GraphicsUtility.PointInsidePolygonTest(poly, pt1)) { return(1); } else { return(-1); } }
internal static Dictionary <string, object> AddPointToFitPoly(Polygon2d poly, Polygon2d containerPoly, double distance = 16, double area = 0, double thresDistance = 10, double recompute = 5) { if (!ValidateObject.CheckPoly(poly)) { return(null); } if (distance < 1) { return(null); } Dictionary <string, object> lineOffsetCheckObj = ValidateObject.CheckLinesOffsetInPoly(poly, containerPoly, distance); List <int> indicesFalse = (List <int>)lineOffsetCheckObj["IndicesFalse"]; List <List <Point2d> > pointsFalse = (List <List <Point2d> >)lineOffsetCheckObj["PointsOutside"]; List <Point2d> probPointList = new List <Point2d>(); List <Point2d> polyNewPoints = new List <Point2d>(); List <Line2d> falseLines = new List <Line2d>(); Point2d ptNewEnd = new Point2d(0, 0); Point2d otherPt = new Point2d(0, 0); Point2d probPt = new Point2d(0, 0); Line2d line = new Line2d(ptNewEnd, otherPt); int count = 0, maxTry = 50; double ratio = 0, increment = .25; bool added = false, checkOffPtNew = false; for (int i = 0; i < poly.Points.Count; i++) { int a = i, b = i + 1; if (i == poly.Points.Count - 1) { b = 0; } polyNewPoints.Add(poly.Points[a]); if (indicesFalse[i] > -1) { falseLines.Add(poly.Lines[i]); } if (poly.Lines[i].Length > thresDistance && indicesFalse[i] > -1 && pointsFalse[i] != null && pointsFalse[i].Count == 1 && !added && LayoutUtility.CheckLineGetsExternalWall(poly.Lines[i], containerPoly)) { probPointList.AddRange(pointsFalse[i]); probPt = pointsFalse[i][0]; line = poly.Lines[i]; Point2d midPt = LineUtility.LineMidPoint(line); if (line.StartPoint.Compare(probPt)) { otherPt = line.EndPoint; } else { otherPt = line.StartPoint; } Vector2d vecToOther = new Vector2d(probPt, otherPt); while (!checkOffPtNew && count < maxTry && ratio < 0.9) { ratio += increment; ptNewEnd = VectorUtility.VectorAddToPoint(probPt, vecToOther, ratio); Point2d offPtNew = LineUtility.OffsetLinePointInsidePoly(line, ptNewEnd, poly, distance); checkOffPtNew = GraphicsUtility.PointInsidePolygonTest(poly, offPtNew); count += 1; } polyNewPoints.Add(ptNewEnd); added = true; } } Polygon2d polyAdded = new Polygon2d(polyNewPoints, 0); return(new Dictionary <string, object> { { "PolyAddedPts", (polyAdded) }, { "ProblemPoint", (probPt) }, { "IsAdded", (added) }, { "PointAdded", (ptNewEnd) }, { "Trials", (count) }, { "FinalRatio", (ratio) }, { "ProblemLine", (line) }, { "ProblemPtsList", (probPointList) }, { "FalseLineList", (falseLines) } }); }
public static Dictionary <string, object> MakeProgCirculationPolys(List <Line2d> circulationNetwork, List <Polygon2d> polyProgList, double circulationWidth = 8, double circulationFrequency = 0.5, int designSeed = 10) { if (!ValidateObject.CheckPolyList(polyProgList)) { return(null); } if (circulationNetwork == null || circulationNetwork.Count == 0) { return(null); } List <Line2d> flatLineList = new List <Line2d>(); List <bool> IsDuplicateList = new List <bool>(); polyProgList = PolygonUtility.SmoothPolygonList(polyProgList, 5); //flatten all the polys in each depts to make it one list List <Polygon2d> circulationPolyList = new List <Polygon2d>(); List <Polygon2d> updatedProgPolyList = new List <Polygon2d>(); List <int> deptIdList = new List <int>(); double allowedCircRatio = 4; List <double> areaProgPolyList = new List <double>(); for (int i = 0; i < polyProgList.Count; i++) { areaProgPolyList.Add(PolygonUtility.AreaPolygon(polyProgList[i])); } double maxArea = areaProgPolyList.Max(); areaProgPolyList.Sort(); int value = (int)(areaProgPolyList.Count / 3); double areaThresh = areaProgPolyList[value]; Random ran = new Random(designSeed); for (int i = 0; i < circulationNetwork.Count; i++) { Line2d splitter = circulationNetwork[i]; double someNumber = BasicUtility.RandomBetweenNumbers(ran, 1, 0); if (someNumber > circulationFrequency) { continue; } for (int j = 0; j < polyProgList.Count; j++) { Polygon2d progPoly = polyProgList[j]; double areaPoly = PolygonUtility.AreaPolygon(progPoly); Point2d midPt = LineUtility.LineMidPoint(splitter); Point2d nudgedMidPt = LineUtility.NudgeLineMidPt(splitter, progPoly, 0.5); bool checkInside = GraphicsUtility.PointInsidePolygonTest(progPoly, nudgedMidPt); if (checkInside) { Dictionary <string, object> splitResult = SplitObject.SplitByLine(progPoly, splitter, circulationWidth); List <Polygon2d> polyAfterSplit = (List <Polygon2d>)(splitResult["PolyAfterSplit"]); if (ValidateObject.CheckPolyList(polyAfterSplit)) { double areaA = PolygonUtility.AreaPolygon(polyAfterSplit[0]), areaB = PolygonUtility.AreaPolygon(polyAfterSplit[1]); if (areaA < areaB) { if (polyAfterSplit[0].Points != null) { if (ValidateObject.CheckPolyBBox(polyAfterSplit[0], allowedCircRatio)) { circulationPolyList.Add(polyAfterSplit[0]); } } updatedProgPolyList.Add(polyAfterSplit[1]); } else { if (polyAfterSplit[1].Points != null) { if (ValidateObject.CheckPolyBBox(polyAfterSplit[1], allowedCircRatio)) { circulationPolyList.Add(polyAfterSplit[1]); } } updatedProgPolyList.Add(polyAfterSplit[0]); } } // end of if loop checking polylist } // end of check inside } // end of for loop j } // end of for loop i return(new Dictionary <string, object> { { "ProgCirculationPoly", (circulationPolyList) } }); }
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) } }); }
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) } }); }