Hexagonal Grids (2013)
redblobgames.com
redblobgames.com
I also love that this isn't just theory; there's an entire implementation guide[1] to all of the concepts discussed here.
[1] https://www.redblobgames.com/grids/hexagons/implementation.h...
I start with hex algorithms written in Haxe. I use Haxe's macro system to turn this into an abstract syntax tree. I then use Haxe's ADT + pattern matching to transform this into a different syntax tree. And then I again use Haxe's ADT + pattern matching to transform this into Python, C++, JavaScript, C#, TypeScript, Lua, Java, and Haxe code. (I also have partial support for Rust and Lisp)
Unlike most "transpilers" I'm trying to generate code that looks reasonably idiomatic for the target language. I transform names and structure (e.g. `hex_add()` for a C global function but `Hex.add()` for a Java class method) and also transform for dynamic types (e.g. Point(x,y) can have numbers in JavaScript but I need a separate Point and FloatPoint for int/float in C++). This means I need to sometimes annotate the original Haxe-syntax code with hints about how it should translate into each language. For example, 1/2 produces a different value in Python (0.5) than in C (0), so I need to add hints to tell the transform code which one I mean.
I also translate the unit tests in this way, and run them as part of the output code.
It's been a fun project but it's grown out of hand. The past week I've been pondering refactoring parts of it.
The reason for all this complexity is that my original goal was to add a language drop-down on the implementation guide page. Then you could read the implementation guide in your choice of language, your choice of grid, your choice of indentation, etc. That was an overly ambitious project :-)
But more importantly, reading/interacting with your work is fun! It enthused me to tinker with the concepts and even to try and go beyond the explained theory and think of other ways to tile, encode maps, represent coordinates, etc.
I could get enthusiastic about almost any subject if it's presented this well.
For more pages like this, look at https://explorabl.es/ — it's a collection of visual/interactive explanations of various topics
I personally have some related ideas for a personal project but haven’t gotten anything done on it.
709 points | 10 years ago | 69 comments https://news.ycombinator.com/item?id=5809724
462 points | 9 years ago | 39 comments https://news.ycombinator.com/item?id=8941588
368 points | 3 years ago | 74 comments https://news.ycombinator.com/item?id=25340425
337 points | 5 years ago | 46 comments https://news.ycombinator.com/item?id=19184412
174 points | 6 years ago | 18 comments https://news.ycombinator.com/item?id=14627711
174 points | 8 years ago | 15 comments https://news.ycombinator.com/item?id=9537009
Weird hobby, but hey, who am I to judge? Thanks for the ultimate resource, I genuinely enjoyed following and interacting with it.
* 59828 different definitions of "triangle center" https://faculty.evansville.edu/ck6/encyclopedia/ETC.html
* Amazing reference on bezier curves https://pomax.github.io/bezierinfo/
* Sunbeam radiant toaster http://automaticbeyondbelief.org/
* How to pack geometric shapes inside other shapes https://erich-friedman.github.io/packing/
* Pictures of library cards https://librarycards.tripod.com/id1.html
* All about pc fans https://nick-black.com/dankwiki/index.php?title=PC_Fans
* Cross sections of candy bars https://scandybars.tumblr.com/
* All kinds of info about bicycles https://www.sheldonbrown.com/
* Every type of plastic used by lego https://bricknerd.com/home/every-type-of-plastic-used-by-leg...
* Ian's Shoelace Site https://www.fieggen.com/shoelace/
"the sierpinski triangle page to end most sierpinski triangle pages ™" — but it's still on wayback machine https://web.archive.org/web/20190322201106/https://www.often...
Packing / bin-packing is very serious stuff: savings made there directly translate to less waste / reduced costs (for example when cutting shapes into sheets of metal in big factories).
> * Amazing reference on bezier curves https://pomax.github.io/bezierinfo/
And some beautiful graphs in there, notably those under section 26 "Curvature of a curve". Screenshot'ed for my own collection of good looking stuff!
Pure joy to interact and learn from resources such as these. Amit Patel - thank you if you ever read this!
Back when I was playing with hex grids, the orientation he was using (pointy top) wasn’t what I wanted to use, so I really wasn’t able to apply any of it to my work.
So I ended up doing it much on my own. I did scavenge Google for a “distance” formula and that took a couple of goes.
I’ll have to read it in more detail to see whether it’s worthwhile to adopt this vs just sticking with what I have.
1. Pointy and flat are 60° rotations away from each other. This is what I use for animations. But it's not as useful for the math.
2. Pointy and flat are the same with x/y flipped. This is much more useful for coding.
It has improved significantly, at least in presentation, over time. Suspect the content has, too, but I have a less-clear recollection to assess the differences in content than I do for presentation from the last time I visited probably 3-5 years ago.
* 2023-02: used the mouse event techniques I described here: https://news.ycombinator.com/item?id=37703291
* 2023-02: added an interactive calculation of the number of hexagons in a spiral
* 2022-12: rewrote the introductory diagrams after trying out many alternative designs; wrote about it https://simblob.blogspot.com/2022/11/introduction-to-hexagon...
* 2022-10: removed server-side rendering, as it was complicating the build process, and it wasn't a clear win (page loaded slower)
* 2022-07: fixed some embarassing typos in the sample code (ugh)
* 2021-11: updated sample code to be easier to read and not use python-specific constructs; updated naming to be more clear about which code works on cube coordinates vs axial coordinates; filled in missing helper functions that I thought would be obvious but I should've included all along
* 2021-10: unified the hex implementation guide, which used q/r/s coordinate names for cube-hexagon and q/r for axial-hexagon and x/y for cartesian, with the hex theory page, which used x/z/y for cube-hexagons and q/r for axial-hexagons and x/y for cartesian. This was the last major update, as it involved updating all the text, diagrams, and sample code. The unification is something I had been wanting to do for several years but I knew it would take a while and it would also break "backwards compatibility" with everyone who had read the x/z/y version. It was especially tricky because x/z/y not x/y/z corresponded to q/r/s, and that's what led to the embarassing typos in code I had to fix later. And the change in order also changed which direction the rotation algorithm worked.
* 2021-01: updated the size & spacing diagram to visually show the relationships between the different measurements
* 2021-01: changed the hex and axis labels to try to make them correspond because it's a bit confusing; see https://simblob.blogspot.com/2021/01/hex-diagram-labels.html
* 2020-12: added a section about reflections https://www.redblobgames.com/grids/hexagons/#reflection
* 2020-04: improved the labels on the cube/hex diagram to try to improve the correspondence between the diagram and text https://www.redblobgames.com/grids/hexagons/#coordinates-cub...
* 2019-04: rewrote the map storage section because I wasn't at all happy with how it was written before; I wrote up the change https://simblob.blogspot.com/2019/03/improving-hexagon-map-s...
* 2019-02: used IntersectionObserver to delay the diagram rendering until you reach that section of the page; this improves page load times
* 2018-05: added the "doubled" coordinate system. It's a pretty nice system, and I didn't know about it when I first wrote the page. I learned about it from rot.js.
I had lots more changes in 2018. I had just reimplemented the entire page (https://simblob.blogspot.com/2018/04/april-updates-hex-grid-...) and that gave me lots of ideas of things to improve. I first rewrote it without changing the diagrams, but then went back and made lots of diagram and text changes.
I think the original idea is from Paul Bourke. He calls it a Spiral Honeycomb Mosaic (SHM).
See his "Tiling on The Plane" page [1]. Scroll down to the section titled "Hexagonal Lattice" (contains links to source code with coordinate conversions).
Here is a Rust implementation of a different variant of the same idea [2].
- https://gamedev.stackexchange.com/questions/71785/converting...
- https://tex.stackexchange.com/questions/275490/is-there-an-e...
- https://github.com/cooscoos/spiral_cube
- https://web.archive.org/web/20160309172431/http://www.pyxisi...
- https://www.sciencedirect.com/science/article/pii/0166218X92...
- https://thoughtstreams.io/jtauber/hex-map-addressing/
- http://tzaphiriron.sidemoon.net/static/hex/hex.html
- https://tilde.zone/@misterdave/109736460410840020
There's so much more to add to the page, and I keep adding over time. Thanks for the link to the hex-spiral crate; I'll add it to my bookmarks.
https://www.redblobgames.com/grids/parts/#more
> Spiral Honeycomb Mosaic [0] (search the page for "Spiral Honeycomb Mosaic") is an interesting way to assign numbers to hexagons in a hexagonal grid. It results in bizarre properties.
If the dimensions aren't independent and/or orthogonal, can this even be called a coordinate system? For example, you can have (1, 4, -5) but you can't have (1, 4, -4).
https://en.wikipedia.org/wiki/Coordinate_system
https://en.wikipedia.org/wiki/Curvilinear_coordinates
More specifically: can you think of coordinate systems with explicit binary or ternary constraints on the parameters in the coordinates? I can't immediately think of any.
Holonomic constraints etc. are constraints on the validity of regions of the space, not constraints on the ability of coordinates to exist.
If I understand correctly, homogeneous coordinates have additional independent dimensions, but are many-to-one instead of constraining their parameters. Maybe normalized homogeneous coordinates? That's not a particularly interesting system.
I'm now second guessing my definition of coordinate system...
The "third coordinate" is only for convenience when working with the three main axes of an hexagonal grid. Without it, the three directions of your grid are {+q, +r, -q-r}, which introduces an ugly asymmetry for one of the three axes.
And check out the other posts on this site. Good stuff.
https://en.m.wikipedia.org/wiki/Star_Fleet_Battles
I played this for days at a time as a kid. Literally.
I first saw this page years ago, when considering a hex grid-based game design, and, despite the page's excellent information, my takeaway was: eh, too complicated, not worth it.
But looking back, it wasn't worth the hassle. Because what's the advantage of hex, apart from looking unusual? If you have, let's say, a road on a map, and some heatmap should highlight it, then cells of rectangular heatmap are going to be like low-res pixel art -- only in 2 directions it coincides with cells and looks nice.
Well, with hex grid you have +50% of such directions. Uber's H3 advocates insist there's also exactly the same distance between cells centroids. Well, that's all advantages.
Anti-bonus of hexgrid: you can't aggregate it. Hexagons don't sum up into bigger hexagons.
[1] https://github.com/culebron/erde/blob/master/erde/op/isochro...
I have seen hex grids used a lot in approximating geographic contours. Its possible that for a given number of cells they do better approximations than a regular, but one would need to check this mathematically
They don't nest perfectly the way squares do, but if you rotate at alternate levels they have a decent approximate 7-in-1 nesting that H3 leverages.
If you have H3 and several million records, every aggregation takes noteable amount of time.
It also means that you must keep those indice for each record for each level. Because the parent function gives wrong cell for points on the fringe.
It depends on the purpose of the aggregation; if you are aggregating based on logical containment and using a consistent grid level for deciding the canonical location, this isn't an issue; if you are doing "aggregation" by doing strict geographical lookup for each datapoint at the grid level of the "aggregate", then it is an issue, but that is not actually an aggregation, that's a separate basic bucketing at each resolution level (though it may be the sensible way to handle data for a particular application.)
In essence, you can use an H3 index at one level as a reference to particular polygon or an a reference to the aggregate of polygons on specified level which are logically contained within it, and which makes sense depends on the application.
It is a true, and a disadvantage for some uses, that these are necessarily different interpretations, and you have to choose and apply one, whereas with lat/long or S2, geographical and logical containment are identical.
If a cell is said to be a sum of 7 underlying cells, then their sum of objects must equal to this cell's sum of objects, which is not the case in H3.
You can just hope that the diff of these values is within acceptable limits, and that company management never tries to drill down into your data, and does not put all the blame for some incorrectness on you.
So, even though H3 cells kinda add-up, they actually don't, and you have to either just plainly hope, or take care of data, as I decided to do.
You'd never had this dilemma, nor need to cure the data, with a rectangular grid in either UTM projection, or Google pseudo-Mecrator, both of which preserve horizontal/vertical aspects and are perfect for such aggregative cell grids.
If you are using an H3 index as an index to the aggregate of the logically-contained cells at some specified level, it absolutely is true (in this case, the exact geographic border is the border of the set of contained cells ay thr specified level, not the border of the higher-level cell specified by the index.)