/// <summary> /// Determines the H3 digit corresponding to a unit vector in ijk coordinates. /// </summary> /// <param name="ijk">The ijk coordinates; must be a unit vector.</param> /// <returns> /// The H3 digit (0-6) corresponding to the ijk unit vector, or /// <see cref="Direction.INVALID_DIGIT"/> INVALID_DIGIT on failure /// </returns> /// <!-- /// coordijk.c /// Direction _unitIjkToDigit /// --> internal static Direction ToDirection(this CoordIjk ijk) { var c = ijk.Normalized(); var test = Constants.CoordIjk.UnitVectors.Where(pair => pair.Value == c).ToList(); return(test.Any() ? test.First().Key : Direction.INVALID_DIGIT); }
/// <summary> /// Determine the containing hex in ijk+ coordinates for a 2D cartesian /// coordinate vector (from <a href="http://www.discreteglobalgrids.org/software/">DGGRID</a>). /// </summary> /// <param name="v">The 2D cartesian coordinate vector.</param> /// <!-- /// coordijk.c /// void _hex2dToCoordIJK /// --> public static CoordIjk ToCoordIjk(this Vec2d v) { var h = new CoordIjk(); // quantize into the ij system and then normalize decimal a1 = Math.Abs(v.X); decimal a2 = Math.Abs(v.Y); // first do a reverse conversion decimal x2 = a2 / Constants.H3.M_SIN60; decimal x1 = a1 + x2 / 2.0m; // check if we have the center of a hex var m1 = (int)x1; var m2 = (int)x2; // otherwise round correctly decimal r1 = x1 - m1; decimal r2 = x2 - m2; if (r1 < 0.5m) { if (r1 < 1.0m / 3.0m) { h = r2 < (1.0m + r1) / 2.0m ? h.SetIJ(m1, m2) : h.SetIJ(m1, m2 + 1); } else { h = r2 < (1.0m - r1) ? h.SetJ(m2) : h.SetJ(m2 + 1); h = (1.0m - r1) <= r2 && r2 < (2.0m * r1) ? h.SetI(m1 + 1) : h.SetI(m1); } } else { if (r1 < 2.0m / 3.0m) { h = r2 < (1.0m - r1) ? h.SetJ(m2) : h.SetJ(m2 + 1); h = (2.0m * r1 - 1.0m) < r2 && r2 < (1.0m - r1) ? h.SetI(m1) : h.SetI(m1 + 1); } else { h = r2 < (r1 / 2.0m) ? h.SetIJ(m1 + 1, m2) : h.SetIJ(m1 + 1, m2 + 1); } } // now fold across the axes if necessary if (v.X < 0.0m) { if (h.J % 2 == 0) // even { long axisI = (long)h.J / 2; long diff = h.I - axisI; h = h.SetI(h.I - (int)(2.0 * diff)); } else { long axisI = (long)(h.J + 1) / 2; long diff = h.I - axisI; h = h.SetI(h.I - (int)(2.0 * diff + 1)); } } if (v.Y < 0.0m) { h = h.SetIJ(h.I - (2 * h.J + 1) / 2, -h.J); } return(h.Normalized()); }