internal int SouthEast(HealCoor basin) { int newRing, newPixelInRing; North(basin.Symmetric(_healpixManager), NeighborHor.West, out newRing, out newPixelInRing); _healpixManager.Symmetric(ref newRing, ref newPixelInRing); return(_healpixManager.GetP(newRing, newPixelInRing)); }
/// <returns>P, index in all HEALPix grid</returns> public int NorthMean(HealCoor basin) { // last basin in north ring var northP = basin.P - basin.PixelInRing; var pixelsInNorthRing = _healpixManager.PixelsCountInRing(basin.Ring - 1); var northPixelInRing = basin.PixelInRing * pixelsInNorthRing / basin.PixelsCountInRing /* _healpixManager.PixelsCountInRing(basin.Ring) */; return(northP - pixelsInNorthRing + Math.Max(1, northPixelInRing)); }
public int Get(Direction direction, HealCoor basin) { switch (direction) { case Direction.Ne: return(NorthEast(basin)); case Direction.Nw: return(NorthWest(basin)); case Direction.Se: return(SouthEast(basin)); default: case Direction.Sw: return(SouthWest(basin)); } }
/// <returns>angle</returns> public double DistanceTo(HealCoor coor) { var φ1 = Phi; var φ2 = coor.Phi; var Δφ = Phi - coor.Phi; var Δλ = Lambda.Value - coor.Lambda.Value; //* haversine formula1 var a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2); var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); return(c); /* Spherical Law of Cosines * * var d = Math.Acos(Math.Sin(φ1) * Math.Sin(φ2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Cos(Δλ)); * * return d; */ }
/// <summary> /// maybe better reuse code from 5.3 Pixel Boundaries /// https://www.researchgate.net/publication/1801816_HEALPix_A_Framework_for_High-Resolution_Discretization_and_Fast_Analysis_of_Data_Distributed_on_the_Sphere /// </summary> public Ray3D MeanBoundary(HealCoor basin, Direction to) { var deltaX = 360d / (basin.PixelsCountInRing * 2); var deltaXsign = GetHor(to) == (int)NeighborHor.East ? 1 : -1; var sameRingBoundaryX = basin.X + deltaXsign * deltaX; var toBasin = _healpixManager.GetCenter <HealCoor>(Get(to, basin)); var toBasinX = toBasin.X; double?toBasinY; if (basin.Ring == 1 && GetVert(to) == NeighborVert.North) { toBasinY = 90; } else if (basin.Ring == _healpixManager.RingsCount && GetVert(to) == NeighborVert.South) { toBasinY = -90; } else { var boundaryRing = basin.Ring + (GetVert(to) == NeighborVert.North ? -1 : 1); var boundaryDeltaX = 360d / (_healpixManager.PixelsCountInRing(boundaryRing) * 2); if (toBasin.Ring == basin.Ring) { var toBasinOppositeHor = _healpixManager.GetCenter <HealCoor>(Get(GetOppositeHor(to), basin)); toBasinY = toBasinOppositeHor.Y; toBasinX = toBasinOppositeHor.X + deltaXsign * boundaryDeltaX; } else { toBasinY = toBasin.Y; toBasinX = toBasinX - deltaXsign * boundaryDeltaX; } } var bisector = Matrixes.Rotate(new HealCoor(toBasinX, toBasinY.Value)) + Matrixes.Rotate(new HealCoor(sameRingBoundaryX, basin.Y)); return(new Ray3D(Basin3.O3, bisector)); }
internal int NorthEast(HealCoor basin) { return(North(basin, NeighborHor.East)); }
private int North(HealCoor basin, NeighborHor hor, out int newRing, out int newPixelInRing) { newRing = basin.Ring - 1; var ringFirstP = basin.P - basin.PixelInRing + 1; var eastIndex = hor == NeighborHor.East ? 1 : 0; int newP; switch (basin.NorthCap) { case true: if ((basin.PixelInRing - eastIndex) % basin.Ring == 0) { newRing++; newP = hor == NeighborHor.East ? basin.EastInRing : basin.WestInRing; } else { newP = basin.P; ringFirstP -= basin.PixelsCountInRing - 4; newP -= basin.PixelsCountInRing - 4 + eastIndex + (basin.PixelInRing - 1) / basin.Ring; } break; case false: newP = basin.P; // border between equator and south cap if (basin.Ring == 3 * _healpixManager.Nside) { ringFirstP -= basin.PixelsCountInRing; newP -= basin.PixelInRing == eastIndex ? 1 : basin.PixelsCountInRing + eastIndex; } else { var ringFromPole = _healpixManager.RingsCount - basin.Ring + 1; ringFirstP -= basin.PixelsCountInRing + 4; newP -= basin.PixelsCountInRing + 4 + (eastIndex == 1 ? 0 : -1) - (basin.PixelInRing - 1) / ringFromPole; } break; default: ringFirstP -= basin.PixelsCountInRing; // exact equator if (basin.Ring % 2 == 0 && _healpixManager.K > 0) { newP = hor == NeighborHor.East ? basin.EastInRing : basin.P; } else { newP = hor == NeighborHor.East ? basin.P : basin.WestInRing; } newP -= basin.PixelsCountInRing; // PixelsCountInRing on equator and first polar cap the same break; } newPixelInRing = newP - ringFirstP + 1; return(newP); }
/// <returns>P, from 0</returns> private int North(HealCoor basin, NeighborHor hor) { int newRing, newPixelInRing; return(North(basin, hor, out newRing, out newPixelInRing)); }