/** * Return the leaf cell containing the given point (a direction vector, not * necessarily unit length). */ public static S2CellId FromPoint(S2Point p) { var face = S2Projections.XyzToFace(p); var uv = S2Projections.ValidFaceXyzToUv(face, p); var i = StToIj(S2Projections.UvToSt(uv.X)); var j = StToIj(S2Projections.UvToSt(uv.Y)); return(FromFaceIj(face, i, j)); }
/** * Given (i, j) coordinates that may be out of bounds, normalize them by * returning the corresponding neighbor cell on an adjacent face. */ private static S2CellId FromFaceIjWrap(int face, int i, int j) { // Convert i and j to the coordinates of a leaf cell just beyond the // boundary of this face. This prevents 32-bit overflow in the case // of finding the neighbors of a face cell, and also means that we // don't need to worry about the distinction between (s,t) and (u,v). i = Math.Max(-1, Math.Min(MaxSize, i)); j = Math.Max(-1, Math.Min(MaxSize, j)); // Find the (s,t) coordinates corresponding to (i,j). At least one // of these coordinates will be just outside the range [0, 1]. const double kScale = 1.0 / MaxSize; var s = kScale * ((i << 1) + 1 - MaxSize); var t = kScale * ((j << 1) + 1 - MaxSize); // Find the leaf cell coordinates on the adjacent face, and convert // them to a cell id at the appropriate level. var p = S2Projections.FaceUvToXyz(face, s, t); face = S2Projections.XyzToFace(p); var st = S2Projections.ValidFaceXyzToUv(face, p); return(FromFaceIj(face, StToIj(st.X), StToIj(st.Y))); }