private void DrawGrid(IMapContext map, Pen penGrid, CelestialGrid grid) { bool isAnyPoint = false; // Azimuths for (int j = 0; j < grid.Columns; j++) { var segments = grid.Column(j) .Select(p => Angle.Separation(grid.ToHorizontal(p, map), map.Center) < map.ViewAngle ? p : null) .Split(p => p == null, true); foreach (var segment in segments) { for (int k = 0; k < 2; k++) { if (segment.First().RowIndex > 1) { segment.Insert(0, grid[segment.First().RowIndex - 1, j]); } } for (int k = 0; k < 2; k++) { if (segment.Last().RowIndex < grid.Rows - 2) { segment.Add(grid[segment.Last().RowIndex + 1, j]); } } PointF[] refPoints = new PointF[2]; for (int k = 0; k < 2; k++) { var coord = grid.FromHorizontal(map.Center, map); coord.Longitude = segment[0].Longitude; coord.Latitude += -map.ViewAngle + k * (map.ViewAngle * 2); coord.Latitude = Math.Min(coord.Latitude, 80); coord.Latitude = Math.Max(coord.Latitude, -80); var refHorizontal = grid.ToHorizontal(coord, map); refPoints[k] = map.Project(refHorizontal); } DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints); isAnyPoint = true; } } // Altitude circles for (int i = 0; i < grid.Rows; i++) { var segments = grid.Row(i) .Select(p => Angle.Separation(grid.ToHorizontal(p, map), map.Center) < map.ViewAngle ? p : null) .Split(p => p == null, true).ToList(); // segment that starts with point "0 degrees" var seg0 = segments.FirstOrDefault(s => s.First().ColumnIndex == 0); // segment that ends with point "345 degrees" var seg23 = segments.FirstOrDefault(s => s.Last().ColumnIndex == 23); // join segments into one if (seg0 != null && seg23 != null && seg0 != seg23) { segments.Remove(seg0); seg23.AddRange(seg0); } foreach (var segment in segments) { if (segment.Count == 24) { map.Graphics.DrawClosedCurve(penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray()); } else { for (int k = 0; k < 2; k++) { int col = segment.First().ColumnIndex; if (col == 0) { segment.Insert(0, grid[i, 23]); } else { segment.Insert(0, grid[i, col - 1]); } } for (int k = 0; k < 2; k++) { int col = segment.Last().ColumnIndex; if (col < 23) { segment.Add(grid[i, col + 1]); } else if (col == 23) { segment.Add(grid[i, 0]); } } PointF[] refPoints = new PointF[2]; for (int k = 0; k < 2; k++) { var coord = grid.FromHorizontal(map.Center, map); coord.Longitude += -map.ViewAngle + k * (map.ViewAngle * 2); coord.Latitude = segment[0].Latitude; var refHorizontal = grid.ToHorizontal(coord, map); refPoints[k] = map.Project(refHorizontal); } if (!map.IsOutOfScreen(refPoints[0]) || !map.IsOutOfScreen(refPoints[1])) { refPoints = map.LineScreenIntersection(refPoints[0], refPoints[1]); } DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints); } isAnyPoint = true; } } // Special case: there are no points visible // on the screen at the current position and zoom. // Then we select one point that is closest to screen senter. if (!isAnyPoint) { GridPoint closestPoint = grid.Points.OrderBy(p => Angle.Separation(grid.ToHorizontal(p, map), map.Center)).First(); { var segment = new List <GridPoint>(); segment.Add(closestPoint); int i = closestPoint.RowIndex; for (int k = 0; k < 2; k++) { int col = segment.First().ColumnIndex; if (col == 0) { segment.Insert(0, grid[i, 23]); } else { segment.Insert(0, grid[i, col - 1]); } } for (int k = 0; k < 2; k++) { int col = segment.Last().ColumnIndex; if (col < 23) { segment.Add(grid[i, col + 1]); } else if (col == 23) { segment.Add(grid[i, 0]); } } PointF[] refPoints = new PointF[2]; for (int k = 0; k < 2; k++) { var coord = grid.FromHorizontal(map.Center, map); coord.Longitude += -map.ViewAngle + k * (map.ViewAngle * 2); coord.Latitude = segment[0].Latitude; var refHorizontal = grid.ToHorizontal(coord, map); refPoints[k] = map.Project(refHorizontal); } if (!map.IsOutOfScreen(refPoints[0]) || !map.IsOutOfScreen(refPoints[1])) { refPoints = map.LineScreenIntersection(refPoints[0], refPoints[1]); } DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints); } { var segment = new List <GridPoint>(); segment.Add(closestPoint); int j = closestPoint.ColumnIndex; for (int k = 0; k < 2; k++) { if (segment.First().RowIndex > 1) { segment.Insert(0, grid[segment.First().RowIndex - 1, j]); } } for (int k = 0; k < 2; k++) { if (segment.Last().RowIndex < grid.Rows - 2) { segment.Add(grid[segment.Last().RowIndex + 1, j]); } } PointF[] refPoints = new PointF[2]; for (int k = 0; k < 2; k++) { var coord = grid.FromHorizontal(map.Center, map); coord.Longitude = segment[0].Longitude; coord.Latitude += -map.ViewAngle + k * (map.ViewAngle * 2); coord.Latitude = Math.Min(coord.Latitude, 80); coord.Latitude = Math.Max(coord.Latitude, -80); var refHorizontal = grid.ToHorizontal(coord, map); refPoints[k] = map.Project(refHorizontal); } DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints); } } }