Good for placing objects around a grid cell! Like this:
(click to interact)Click/tap to select point
You give the function a grid XY and it tells you where the next point should be to have it go in a spiral.
Story time
Once upon a time, before I was known for much of anything, I used to do all sorts of odd jobs, including plugins for Minecraft servers.
The tasks usually involved making various plugins work together or extending plugins to do something new. Small work, small pay.
At one point, some peeps I knew were making a new server based on Skyblock, a game mode where you start on a tiny flying island and use "renewable" resources (like wood logs or items that drop from naturally spawning creatures) to build yourself a base and generally progress.
They faced a few challenges with an existing plugin, one of which was the plugin's placement of islands - a part of the appeal in playing this mode online is seeing other people do their thing on their island nearby,
but the plugin both placed islands too far apart and in no apparent pattern, which meant that most of the times a player would only have one "neighbour", and that would usually be an abandoned island as the mode does take some patience.
In my implementation, the islands were placed closer by in this kind of spiral pattern, and abandoned islands would eventually be recycled to make space for new ones, so the players would always see something happening around them.
As larger server networks caught on the Skyblock trend, the server became a much smaller community and eventually shut down, but some ideas remain.
The code
So it's just this, really (in JS):
function spiralNext(x, y) { var r = Math.max(Math.abs(x), Math.abs(y)); if (y == r) { // bottom edge, going right return { x: x + 1, y: y }; } else if (y == -r) { // top edge, going left until we hit the top-left corner if (x != -r) return { x: x - 1, y: y }; } if (x >= 0) { // right edge, going up return { x: x, y: y - 1 }; } else { // left edge, going down return { x: x, y: y + 1 }; } }
There might be a cleaner way to write this.
Diamond/rotated?
This one's better in terms of distance to the center:
(click to interact)Click/tap to select point
And the code looks slightly nicer!
function spiralNext(x, y) { var r = Math.abs(x) + Math.abs(y); if (y == r) return { x: x + 1, y: y }; if (x > 0) { if (y > 0) { return { x: x + 1, y: y - 1 }; } else { return { x: x - 1, y: y - 1 }; } } else { if (y < 0) { return { x: x - 1, y: y + 1 }; } else { return { x: x + 1, y: y + 1 }; } } }
And that's about it.
Thanks for reading!