diff --git a/libs/h3/src/main/java/org/elasticsearch/h3/CoordIJK.java b/libs/h3/src/main/java/org/elasticsearch/h3/CoordIJK.java index ec6cedb160a48..e57f681fc2eae 100644 --- a/libs/h3/src/main/java/org/elasticsearch/h3/CoordIJK.java +++ b/libs/h3/src/main/java/org/elasticsearch/h3/CoordIJK.java @@ -111,6 +111,15 @@ public Vec2d ijkToHex2d() { return new Vec2d(i - 0.5 * j, j * Constants.M_SQRT3_2); } + /** + * Find the center point in spherical coordinates of a hex on a particular icosahedral face. + */ + public LatLng ijkToGeo(int face, int res, boolean substrate) { + final int i = Math.subtractExact(this.i, this.k); + final int j = Math.subtractExact(this.j, this.k); + return Vec2d.hex2dToGeo(i - 0.5 * j, j * Constants.M_SQRT3_2, face, res, substrate); + } + /** * Add ijk coordinates. * @@ -270,12 +279,10 @@ public void neighbor(int digit) { * clockwise aperture 7 grid. */ public void upAp7r() { - i = Math.subtractExact(this.i, this.k); - j = Math.subtractExact(this.j, this.k); - final int i = (int) Math.round((Math.addExact(Math.multiplyExact(2, this.i), this.j)) / 7.0); - final int j = (int) Math.round((Math.subtractExact(Math.multiplyExact(3, this.j), this.i)) / 7.0); - this.i = i; - this.j = j; + final int i = Math.subtractExact(this.i, this.k); + final int j = Math.subtractExact(this.j, this.k); + this.i = (int) Math.round((Math.addExact(Math.multiplyExact(2, i), j)) / 7.0); + this.j = (int) Math.round((Math.subtractExact(Math.multiplyExact(3, j), i)) / 7.0); this.k = 0; ijkNormalize(); } @@ -286,12 +293,10 @@ public void upAp7r() { * */ public void upAp7() { - i = Math.subtractExact(this.i, this.k); - j = Math.subtractExact(this.j, this.k); - final int i = (int) Math.round((Math.subtractExact(Math.multiplyExact(3, this.i), this.j)) / 7.0); - final int j = (int) Math.round((Math.addExact(Math.multiplyExact(2, this.j), this.i)) / 7.0); - this.i = i; - this.j = j; + final int i = Math.subtractExact(this.i, this.k); + final int j = Math.subtractExact(this.j, this.k); + this.i = (int) Math.round((Math.subtractExact(Math.multiplyExact(3, i), j)) / 7.0); + this.j = (int) Math.round((Math.addExact(Math.multiplyExact(2, j), i)) / 7.0); this.k = 0; ijkNormalize(); } diff --git a/libs/h3/src/main/java/org/elasticsearch/h3/FaceIJK.java b/libs/h3/src/main/java/org/elasticsearch/h3/FaceIJK.java index 605fd6c1ea4fc..df2ab26ca0686 100644 --- a/libs/h3/src/main/java/org/elasticsearch/h3/FaceIJK.java +++ b/libs/h3/src/main/java/org/elasticsearch/h3/FaceIJK.java @@ -421,8 +421,7 @@ public Overage adjustOverageClassII(int res, boolean pentLeading4, boolean subst * @param res The H3 resolution of the cell. */ public LatLng faceIjkToGeo(int res) { - Vec2d v = coord.ijkToHex2d(); - return v.hex2dToGeo(face, res, false); + return coord.ijkToGeo(face, res, false); } /** @@ -526,8 +525,7 @@ public CellBoundary faceIjkPentToCellBoundary(int res, int start, int length) { // vert == start + NUM_PENT_VERTS is only used to test for possible // intersection on last edge if (vert < start + Constants.NUM_PENT_VERTS) { - final Vec2d vec = fijk.coord.ijkToHex2d(); - final LatLng point = vec.hex2dToGeo(fijk.face, adjRes, true); + final LatLng point = fijk.coord.ijkToGeo(fijk.face, adjRes, true); boundary.add(point); } lastFace = fijk.face; @@ -651,8 +649,7 @@ public CellBoundary faceIjkToCellBoundary(final int res, final int start, final // vert == start + NUM_HEX_VERTS is only used to test for possible // intersection on last edge if (vert < start + Constants.NUM_HEX_VERTS) { - final Vec2d vec = fijk.coord.ijkToHex2d(); - final LatLng point = vec.hex2dToGeo(fijk.face, adjRes, true); + final LatLng point = fijk.coord.ijkToGeo(fijk.face, adjRes, true); boundary.add(point); } lastFace = fijk.face; diff --git a/libs/h3/src/main/java/org/elasticsearch/h3/Vec2d.java b/libs/h3/src/main/java/org/elasticsearch/h3/Vec2d.java index 003a696f1dc0a..12ce728a99967 100644 --- a/libs/h3/src/main/java/org/elasticsearch/h3/Vec2d.java +++ b/libs/h3/src/main/java/org/elasticsearch/h3/Vec2d.java @@ -96,7 +96,7 @@ final class Vec2d { } /** - * Determines the center point in spherical coordinates of a cell given by 2D + * Determines the center point in spherical coordinates of a cell given by this 2D * hex coordinates on a particular icosahedral face. * * @param face The icosahedral face upon which the 2D hex coordinate system is @@ -106,8 +106,24 @@ final class Vec2d { * grid relative to the specified resolution. */ public LatLng hex2dToGeo(int face, int res, boolean substrate) { + return hex2dToGeo(this.x, this.y, face, res, substrate); + } + + /** + * Determines the center point in spherical coordinates of a cell given by the provided 2D + * hex coordinates on a particular icosahedral face. + * + * @param x The x component of the 2D hex coordinates. + * @param y The y component of the 2D hex coordinates. + * @param face The icosahedral face upon which the 2D hex coordinate system is + * centered. + * @param res The H3 resolution of the cell. + * @param substrate Indicates whether or not this grid is actually a substrate + * grid relative to the specified resolution. + */ + static LatLng hex2dToGeo(double x, double y, int face, int res, boolean substrate) { // calculate (r, theta) in hex2d - double r = v2dMag(); + double r = Math.sqrt(x * x + y * y); if (r < Constants.EPSILON) { return faceCenterGeo[face]; @@ -283,15 +299,6 @@ public static Vec2d v2dIntersect(Vec2d p0, Vec2d p1, Vec2d p2, Vec2d p3) { return new Vec2d(p0.x + (t * s1x), p0.y + (t * s1y)); } - /** - * Calculates the magnitude of a 2D cartesian vector. - * - * @return The magnitude of the vector. - */ - private double v2dMag() { - return Math.sqrt(x * x + y * y); - } - /** * Normalizes radians to a value between 0.0 and two PI. *