GithubHelp home page GithubHelp logo

Comments (9)

dfellis avatar dfellis commented on July 1, 2024 1

To expand a bit on this, hexagons don't map onto a sphere, so there can't be a singular grid system for the entire globe. H3 almost accomplishes this by being a grid system on equilateral triangles and then arranging them into an icosahedron such that the points of the icosahedron map to 12 special pentagons, leaving the rest to be hexagons.

The only 2D grid that can work is isolated to one of the icosahedron faces. It would be possible to unfold the icosahedron into a Dymaxion Map and then apply the right transformations to allow traversal between icosahedron faces, but that would lead to "edge of the world" problems where you can define hexagons that map to nothing. It can work if you know you are constrained to land only, though, and it is one of the things that has been discussed to potentially offer, but with all of those caveats above.

However, you have not explained what exactly you are trying to accomplish with the game. I am going to make some educated guesses:

  1. The user has GPS coordinates from their phone. This can be translated to H3 with geoToH3.
  2. You need to look up relevant data to show on the map for the player. This can be accomplished with kRing to get the indexes to query your server, with the size based on how far out the map is zoomed, the resolution you choose to operate on, and so on.
  3. You need other operations, like pathing (h3Line), hexagon neighbors (kRing of 1 to get, h3IndexesAreNeighbors to check), outlines for rendering (h3ToGeoBoundary), calculating hex-level distances for attack ranges (h3Distance), etc.

I don't see the explicit need for a 2D grid for the game logic. The various APIs of H3 are designed to give you most of the optionality of a grid despite that being impossible on the sphere. If there is an operation that we have missed, we would be glad to hear about that and add it, but the exact request is technically not possible.

from h3-js.

dfellis avatar dfellis commented on July 1, 2024 1

First, on your questions about H3: the algorithm is (simplified a bit) (lat, lng) -> (x, y, z) (to spherical coordinates), then (x, y, z) -> (x, y) + icosahedron face id (to hex2d, per icosahedron) then (x, y) + icosahedron -> FaceIJK (icosahedron face + (i, j, k) (where IJK here is a 2D coordinate system such that all values are positive and therefore storable inside of an integer) and finally to the H3 Index where it is subdivided such that each 3-bit segment stores a value 0-6 corresponding to one of the IJK subdivision+traversal steps.

It is possible to rederive the original XYZ spherical coordinates from the H3 cells, but involving H3 at all would be a waste of your time, as the conversion from (lat, lng) -> (x, y, z) is literally just this:

void _geoToVec3d(const GeoCoord* geo, Vec3d* v) {
    double r = cos(geo->lat);

    v->z = sin(geo->lat);
    v->x = cos(geo->lon) * r;
    v->y = sin(geo->lon) * r;
}

But if you did go with spherical coordinates, you'd need a 3D perlin noise algorithm and some way to sample out from the unit sphere of that noise to then generate what you're actually after.

If the main thing you're after from H3 is the ability to generate perlin noise on a sphere, I would have to point you to the Google S2 project that this was was inspired by. You would be working with square-ish indexes, and while you do still have the issue that boundaries along the 6 cube faces would have weird traversal rules and odd boundary behavior for the perlin noise if you unfolded that, it could be possible to simply compute the noise 6 times for each unfolding and sum them together and divide by 6 to avoid it.

It should be possible to port a perlin noise function to H3 (unfold the icosahedron centered on each face, then use IJ coordinates then translate back), but it would still have the same unfolding problem, except now you have 20 icosahedron faces to deal with so your function would be ~3x slower to accommodate the boundary problem.

Finally, the fastest way to generate perlin noise on the sphere is to just use (r, theta, phi) with a fixed r you can ignore, and some sort of consideration for the antimerdian problem if you care about that at all (it's also mostly over water). (EDIT 2: Which is basically lat, lng.)

Edit: I missed one last part about how H3 handles hexagons in multiple faces: there are a fixed set of these and they are assigned to one of the two bisecting faces following a rule to make sure all faces have an equal number of hexagons. I don't recall the rule off the top of my head, but the H3 code doesn't compute it, either, the 122 base cells are simply stored in the code with which face they are associated with.

from h3-js.

dfellis avatar dfellis commented on July 1, 2024

For your exact question, the h3ToGeo function does this.

from h3-js.

douglasg14b avatar douglasg14b commented on July 1, 2024

I should clarify, since you are right, that provides lat/long which IS how I can get cartesian coordinates for hexagons. But I don't think that will work in my case. Lat/long wasn't something I thought to address when writing this.

I need a way to get [0,1], [0, 2], [500, 79136]....etc To feed into noise functions for procedural generation, unless I can guarantee that the lat/long for each neighboring cell has a value that allows me to iterate each by only 1 on each axis.

Then again, I could be missing the obvious solution.

from h3-js.

dfellis avatar dfellis commented on July 1, 2024

I should clarify, since you are right, that provides lat/long which IS how I can get cartesian coordinates for hexagons. But I don't think that will work in my case. Lat/long wasn't something I thought to address when writing this.

I need a way to get [0,1], [0, 2], [500, 79136]....etc To feed into noise functions for procedural generation, unless I can guarantee that the lat/long for each neighboring cell has a value that allows me to iterate each by only 1 on each axis.

Then again, I could be missing the obvious solution.

You responded while I was writing that up, give me a sec.

from h3-js.

douglasg14b avatar douglasg14b commented on July 1, 2024

Sorry about that! I made edits while you where writing

The distortion of using H3 on a mercator projection is completely acceptable to me, and the "edge of the world" problems are acceptable as well as this game is constrained to places people can physically go with cell reception. The likelihood of encountering one of the pentagons is extremely low, and in that instance the player can just deal with it not working right at that location.

from h3-js.

dfellis avatar dfellis commented on July 1, 2024

I need a way to get [0,1], [0, 2], [500, 79136]....etc To feed into noise functions for procedural generation, unless I can guarantee that the lat/long for each neighboring cell has a value that allows me to iterate each by only 1 on each axis.

So procedural generation just requires that you have a repeatable seed input. The H3 index itself can act as that seed. The indexes are just 64-bit numbers starting with a base cell and then a series of 3-bit subsections to index the seven subdivisions 0-6 (with 7 indicating not-used). You could break it up if you want/need to (eg, have cells nearby more likely to have similar procedurally generated data) but the ID itself would work fine as a seed.

from h3-js.

dfellis avatar dfellis commented on July 1, 2024

If you want to have that property, that cells nearer to each other are more likely to be similar, there are two approaches: you can key on base cell and then each child sub division 0-6 is equivalent to either "staying put" or "moving in a direction" and you can treat that as IJK or IJ, etc.

However, H3 is also has the property that values that are close to each other numerically are also usually close to each other spatially (it does have discontinuities, but that would exist with any conversion of a 2D plane to a 1D index), so if you don't need that level of precision, simple ordering could suffice.

from h3-js.

douglasg14b avatar douglasg14b commented on July 1, 2024

I greatly appreciate your guidance on this. Unfortunately I am not prepared to roll my own noise algorithms, and am simply used pre-existing ones that I have manipulated to get the map features I am aiming for.

The trouble with pre-existing functions like perlin & simplex noise is that these functions expect x,y coords (Or x,y,z) to generate their noise, the relation those coordinates have with each other is their closeness. This should describe the point better than I can: https://en.wikipedia.org/wiki/Perlin_noise#Algorithm_detail

I don't believe this could function with coordinate values that are significantly spaced, or that don't have closeness to each other in a consistent manner.


Lets shift direction and address a couple items only within the scope of H3, so I can get some facts straight.

The H3 docs mention that the IJK coordinates are used internally by H3. It also implies that the Hex2d coordinates are derived from those. Are these obtainable in some way? And is their uniqueness constrained to each icosahedron face, or to the entire grid?

The uniqueness being constrained to just a face would still work for my case (Not perfect, but it would still work), though I'd need to clarify how H3 handles the coordinates for those hexagons that are in multiple faces.

from h3-js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.