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