//visualize glare lines public static List <Line3d> VisualizeGlareLines(List <Point3d> floorPoints, List <Point3d> furniturePoints, List <Point3d> lightPoints, double threshDist = 10, int index = 0) { for (int i = 0; i < floorPoints.Count; i++) { List <Point3d> selectedPts = new List <Point3d>(); Point2d pt2FloorPt = ConvertToPoint2d(floorPoints[i]); for (int j = 0; j < furniturePoints.Count; j++) { Point2d pt2Furniture = ConvertToPoint2d(furniturePoints[j]); double distance = PointUtility.DistanceBetweenPoints(pt2Furniture, pt2FloorPt); if (distance < threshDist) { selectedPts.Add(furniturePoints[j]); } }// end of j for loop if (selectedPts.Count > 1) { lightPoints.AddRange(selectedPts); } } List <Line3d> glareLines = new List <Line3d>(); for (int i = 0; i < lightPoints.Count; i++) { if (lightPoints[i].X > floorPoints[index].X) { glareLines.Add(new Line3d(floorPoints[index], lightPoints[i])); } } return(glareLines); }
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) } }); }
//check if a given polygon2d has any of its longer edges aligned with any edge of the containerpolygon2d internal static bool CheckPolyGetsExternalWall(Polygon2d poly, Polygon2d containerPoly, double shortEdgeDist = 16, bool tag = true) { bool check = false; if (!ValidateObject.CheckPoly(poly)) { return(check); } Polygon2d polyReg = new Polygon2d(null); //make given polys reduce number of points if (tag) { polyReg = new Polygon2d(poly.Points); } else { polyReg = poly; } Polygon2d containerPolyReg = new Polygon2d(containerPoly.Points); for (int i = 0; i < polyReg.Points.Count; i++) { int a = i, b = i + 1; double eps = 0; if (i == polyReg.Points.Count - 1) { b = 0; } double distance = PointUtility.DistanceBetweenPoints(polyReg.Points[a], polyReg.Points[b]); List <double> spansSorted = PolygonUtility.GetPolySpan(containerPolyReg); if (distance <= spansSorted[0] * 0.75) { continue; } Line2d lineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], polyReg.Points[b]); for (int j = 0; j < containerPolyReg.Points.Count; j++) { int c = j, d = j + 1; if (j == containerPolyReg.Points.Count - 1) { d = 0; } Line2d lineB = Line2d.ByStartPointEndPoint(containerPolyReg.Points[c], containerPolyReg.Points[d]); check = GraphicsUtility.LineAdjacencyCheck(lineA, lineB, eps); if (check) { break; } } if (check) { break; } } return(check); }
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) } }); }
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) } }); }
// finds the angle between two points wrt Origin - not sure internal static double AngleBetweenPoint2d(Point2d A, Point2d center) { double angle = Math.Acos((A.X - center.X) / PointUtility.DistanceBetweenPoints(center, A)); if (A.Y < center.Y) { angle = Math.PI + Math.PI - angle; //360-angle } return(angle); //return angle*180/Math.PI; }
//pushes the line midpt towards the center of the given polygon2d internal static Point2d NudgeLineMidPt(Line2d line, Polygon2d poly, double scale = 0.2) { Point2d midPt = LineMidPoint(line); Point2d polyCenter = PointUtility.CentroidInPointLists(poly.Points); Vector2d vecToCenter = new Vector2d(midPt, polyCenter); Vector2d vecNormalized = vecToCenter.Normalize(); Vector2d vecScaled = vecNormalized.Scale(scale); return(new Point2d(midPt.X + vecScaled.X, midPt.Y + vecScaled.Y)); }
// find the centroid of a group of cells internal static Point2d CentroidInCells(List <Cell> cellList) { List <Point2d> ptList = new List <Point2d>(); for (int i = 0; i < cellList.Count; i++) { ptList.Add(cellList[i].CenterPoint); } return(PointUtility.CentroidInPointLists(ptList)); }
//line and polygon intersection - not using now public static Line2d LinePolygonIntersectionReturnLine(List <Point2d> poly, Line2d testLine, Point2d centerPt) { Random ran = new Random(); double dist = 10000000000000000; SortedDictionary <double, Line2d> sortedIntersectionLines = new SortedDictionary <double, Line2d>(); List <Point2d> ptList = new List <Point2d>(); double x = (testLine.StartPoint.X + testLine.EndPoint.X) / 2; double y = (testLine.StartPoint.Y + testLine.EndPoint.Y) / 2; Point2d midPt = new Point2d(x, y); Line2d intersectedLineInPoly = null; int count = 0; for (int i = 0; i < poly.Count - 1; i++) { Point2d pt1 = poly[i]; Point2d pt2 = poly[i + 1]; Line2d edge = new Line2d(pt1, pt2); if (LineLineIntersectionNew(edge, testLine) != null) { double xE = (edge.StartPoint.X + edge.EndPoint.X) / 2; double yE = (edge.StartPoint.Y + edge.EndPoint.Y) / 2; Point2d EdgeMidPt = new Point2d(xE, yE); double checkDist = PointUtility.DistanceBetweenPoints(centerPt, EdgeMidPt); try { sortedIntersectionLines.Add(checkDist, edge); } catch (Exception) { double eps = ran.NextDouble() * 2; double newDist = checkDist - eps; sortedIntersectionLines.Add(newDist, edge); } intersectedLineInPoly = edge; count += 1; } } if (sortedIntersectionLines.Count > 0) { foreach (KeyValuePair <double, Line2d> p in sortedIntersectionLines) { intersectedLineInPoly = p.Value; break; } } else { intersectedLineInPoly = null; } return(intersectedLineInPoly); }
//moves a line by a given distance inside a given poly internal static Line2d Move(Line2d line, List <Point2d> poly, double distance) { Point2d midPt = LineMidPoint(line); Point2d centerPoly = PointUtility.CentroidInPointLists(poly); Vector2d vecToCenter = new Vector2d(midPt, centerPoly); Vector2d vecToCenterN = vecToCenter.Normalize(); Vector2d vectScaled = vecToCenter.Scale(distance); Point2d start = new Point2d((line.StartPoint.X + vectScaled.X), (line.StartPoint.Y + vectScaled.Y)); Point2d end = new Point2d((line.EndPoint.X + vectScaled.X), (line.EndPoint.Y + vectScaled.Y)); return(new Line2d(start, end)); }
//joins two collinear lines to make one line public static Line2d JoinCollinearLines(Line2d lineA, Line2d lineB) { List <Point2d> allPoints = new List <Point2d>(); allPoints.Add(lineA.StartPoint); allPoints.Add(lineA.EndPoint); allPoints.Add(lineB.StartPoint); allPoints.Add(lineB.EndPoint); int p = PointUtility.LowestPointFromList(allPoints); int q = PointUtility.HighestPointFromList(allPoints); Line2d lineJoined = new Line2d(allPoints[p], allPoints[q]); return(lineJoined); }
//computes the UGR value internal static double CalculateUGR(List <Point3d> lightPts, Point3d observer, List <double> posList, double lightSize = 2, double recompute = 1) { double backLum = 10; double lumin = 10; double angleEach = 0; double guthPos = 2; double value = 0; double summation = 0; int pos = 0, m = 0; for (int i = 0; i < lightPts.Count; i++) { if (m < posList.Count && i == (int)posList[m]) { lumin = recompute * lumin; m += 1; } else { lumin = 10; } if (lightPts[i].X > observer.X) { Point2d ptLight2d = ConvertToPoint2d(lightPts[i]); Point2d ptObserver2d = ConvertToPoint2d(observer); double distance = PointUtility.DistanceBetweenPoints(ptLight2d, ptObserver2d); guthPos = distance; Point3d lightPt1 = new Point3d((lightPts[i].X - lightSize), (lightPts[i].Y - lightSize), lightPts[i].Z); Point3d lightPt2 = new Point3d((lightPts[i].X + lightSize), (lightPts[i].Y + lightSize), lightPts[i].Z); Vector3d vec1 = new Vector3d(observer, lightPt1); Vector3d vec2 = new Vector3d(observer, lightPt2); angleEach = VectorUtility.AngleBetweenVec3d(vec1, vec2); summation += (lumin * lumin * angleEach) / (guthPos * guthPos); } } value = (0.25 / backLum) * summation; if (value == 0) { return(0); } double ugr = 8 * Math.Log10(value); if (ugr < 0) { ugr = 0; } return(ugr); }
//sorts list of points by distance from a given point public static List <Point2d> SortPointsByDistanceFromPoint(List <Point2d> ptList, Point2d testPoint) { List <Point2d> sortedPtList = new List <Point2d>(); List <double> distanceList = new List <double>(); List <int> indexList = new List <int>(); for (int i = 0; i < ptList.Count; i++) { distanceList.Add(PointUtility.DistanceBetweenPoints(ptList[i], testPoint)); } indexList = BasicUtility.SortIndex(distanceList); for (int i = 0; i < indexList.Count; i++) { sortedPtList.Add(ptList[indexList[i]]); } return(sortedPtList); }
} // end of function //makes intersections and returns the two polygon2ds after intersection internal static Dictionary <string, object> MakeIntersections(List <Point2d> poly, Line2d splitLine, double space = 0) { List <Point2d> intersectedPoints = GraphicsUtility.LinePolygonIntersection(poly, splitLine); //List<Point2d> intersectedPoints = TestGraphicsUtility.LinePolygonIntersectionIndex(poly, splitLine); // find all points on poly which are to the left or to the right of the line List <int> pIndexA = new List <int>(); List <int> pIndexB = new List <int>(); for (int i = 0; i < poly.Count; i++) { bool check = ValidateObject.CheckPointSide(splitLine, poly[i]); if (check) { pIndexA.Add(i); } else { pIndexB.Add(i); } } //organize the points to make closed poly List <Point2d> sortedA = PointUtility.DoSortClockwise(poly, intersectedPoints, pIndexA); List <Point2d> sortedB = PointUtility.DoSortClockwise(poly, intersectedPoints, pIndexB); /*List<Polygon2d> splittedPoly = new List<Polygon2d>(); * if (space == 0) splittedPoly = new List<Polygon2d> { new Polygon2d(sortedA, 0), new Polygon2d(sortedB, 0) }; * else * { * sortedA = PolygonUtility.SmoothPolygon(new Polygon2d(sortedA,0).Points, space); * sortedB = PolygonUtility.SmoothPolygon(new Polygon2d(sortedB,0).Points, space); * splittedPoly = new List<Polygon2d> { new Polygon2d(sortedA, 0), new Polygon2d(sortedB, 0) }; * } */ List <Polygon2d> splittedPoly = new List <Polygon2d> { new Polygon2d(sortedA, 0), new Polygon2d(sortedB, 0) }; return(new Dictionary <string, object> { { "PolyAfterSplit", (splittedPoly) }, { "IntersectedPoints", (intersectedPoints) }, { "PointASide", (sortedA) }, { "PointBSide", (sortedB) } }); }
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) } }); }
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) } }); }
//compute glare values public static List <List <double> > ComputeGlareValues(List <Point3d> floorPoints, List <Point3d> furniturePoints, List <Point3d> lightPoints, double threshDist = 10, double lightSize = 3, double numSpecialLights = 2, double recompute = 1) { int pos = 0; List <double> posList = new List <double>(); List <double> distList = new List <double>(); List <double> ugrList = new List <double>(); int count = 0; double numD = BasicUtility.RandomBetweenNumbers(new Random(), 0.1, 0.35); for (int i = 0; i < numSpecialLights; i++) { posList.Add(lightPoints.Count * (i + 1) * numD); } pos = (int)(lightPoints.Count * 0.20); for (int i = 0; i < floorPoints.Count; i++) { List <Point3d> selectedPts = new List <Point3d>(); Point2d pt2FloorPt = ConvertToPoint2d(floorPoints[i]); for (int j = 0; j < furniturePoints.Count; j++) { Point2d pt2Furniture = ConvertToPoint2d(furniturePoints[j]); double distance = PointUtility.DistanceBetweenPoints(pt2Furniture, pt2FloorPt); distList.Add(distance); if (distance < threshDist) { selectedPts.Add(furniturePoints[j]); } }// end of j for loop if (selectedPts.Count > 0) { lightPoints.AddRange(selectedPts); } double ugrValue = CalculateUGR(lightPoints, floorPoints[i], posList, lightSize, recompute); ugrList.Add(ugrValue); count += 1; } List <double> val2 = new List <double>(), val3 = new List <double>(); for (int n = 0; n < ugrList.Count; n++) { val2.Add(0); val3.Add(0); } List <double> ugrListNormalized = BasicUtility.NormalizeList(ugrList, 0, 255); List <List <double> > result = new List <List <double> >(); result.Add(ugrListNormalized); result.Add(val2); result.Add(val3); result.Add(distList); result.Add(new List <double> { count }); result.Add(ugrList); result.Add(new List <double> { lightSize }); result.Add(posList); return(result); }
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) }, }); }