惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
博客园_首页
S
SegmentFault 最新的问题
罗磊的独立博客
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
D
Docker
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
博客园 - 司徒正美
V
V2EX
大猫的无限游戏
大猫的无限游戏
V
Visual Studio Blog
腾讯CDC
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
Vercel News
Vercel News
H
Help Net Security
博客园 - Franky
D
DataBreaches.Net
aimingoo的专栏
aimingoo的专栏

Red Blob Games: latest blog posts

Red Blob Games: Differential heuristics Red Blob Games: Responsive design calculator Red Blob Games: Academic citations Red Blob Games: Highlighting interactive code blocks Red Blob Games: Optimizing page size Red Blob Games: Writing a guide to SDF fonts Red Blob Games: URLs with trailing punctuation Red Blob Games: What I did in 2025 Red Blob Games: Goodbye Sass Goodbye Sass Red Blob Games: RotMG map seeds Red Blob Games: Mapgen4 Mapgen4's use of WebGL2 Red Blob Games: Mapgen4 river shader Red Blob Games: Mapgen4 renderer Red Blob Games: Harnessing ChatGPT hallucinations Red Blob Games: Let Let's write a search engine, part 2 of 2 Red Blob Games: Let Let's write a search engine, part 1 of 2 Red Blob Games: Mapgen4 trade routes Red Blob Games: De-optimizing mapgen4 Red Blob Games: Hexagon spiral coordinates Red Blob Games: Thoughts on Flash Red Blob Games: What I did in 2024 Red Blob Games: Hexagon page animations Red Blob Games: SDF Halos SDF Halos Red Blob Games: SDF headless tests, part 2 Red Blob Games: SDF headless tests, part 1
Red Blob Games: Hexagon conversions
2025-05-29 · via Red Blob Games: latest blog posts

My hexagon guide[1] has many conversion routines — axial to cube, cube to offset, hex to pixel, etc. Sometimes these steps can be combined into larger steps or separated into smaller steps. There’s a balancing act between:

  1. give the reader the final answer
  2. give the reader the ingredients so they can adapt them as needed

My original goal was to provide code for these 22 conversions:

conversions-all.png

However, I didn’t know all the conversion formulas, and ended up providing only these 16:

conversions-initial.png

So that means if you want to go in reverse from pixel to odd_r, you build the chain pixelaxialcubeodd_r. Not great.

Things got more complicated when I added doubled_h, doubled_v. And I want to add several spiral systems:

conversions-more.png

Last week I wanted to add conversions for non-uniform pixel sizes. That was adding far more edges to this graph. I simplified by splitting the pixel conversion into multiple steps:

conversions-steps.png

The problem is that … I think most readers want a formula that solves their problem. Breaking things into steps makes it easier for me, and I think it’s better for understanding what’s going on, but it’s less convenient for the reader. I took the single step conversion from axial to pixel:

Before: single step axial to pixel

And split it into axial to cartesian and then scaling the cartesian:

After: separate scaling step

Why? Because it allows scaling non-uniformly, to match a desired pixel art size:

Non-uniform scaling

If we inline the calculations we end up with this:

Non-uniform scaling

It’s nice. There’s no more sqrt(3) there!

By keeping the steps separate, it allows for adapting to more situations:

  • translate transform to get a non-zero origin
  • scale transform to get non-regular hexagon sizes
  • rotation transform to get angles other than “pointy” and “flat”
  • isometric view combined a shear and rotation operation

I think it’s easier to understand inverting the process from hex-to-pixel to pixel-to-hex when the steps are separate. I have mixed feelings about this change but I made it in part because I wanted to show how to adjust the conversions to match the size of art assets.

You can see the new code in the hex-to-pixel[2] and pixel-to-hex[3] sections of the hexagons guide. I’ve added a section where you can enter the pixel art asset size, and I output the conversion routine. Maybe I can extend that interactive code generator to work for all the coordinate systems. Let me know what you think. I might change it back based on feedback.

While working on this section, I realized I want to add more direct support for doubled coordinates. It probably makes more sense to go from offset coordinates to doubled to pixel than offset to cube to axial to pixel. But that will wait for another day. [Update: that day was in mid-June.]

I also realized that the main page has pixel-to-hex that returns a rounded value, but the implementation guide has a pixel-to-hex that returns a fractional value, and you have to round it yourself. That’s because the fractional value is sometimes useful. I updated the implementation guide to provide both.