What is an algorithm to get the nth element of a rectangular tiled spiral?
Here is n
:
[ 20 ][ 21 ][ 22 ][ 23 ][ 24 ]
[ 19 ][ 6 ][ 7 ][ 8 ][ 9 ]
[ 18 ][ 5 ][ 0 ][ 1 ][ 10 ]
[ 17 ][ 4 ][ 3 ][ 2 ][ 11 ]
[ 16 ][ 15 ][ 14 ][ 13 ][ 12 ]
and here are the corresponding coordinates for n
:
[-2,2 ][-1,2 ][ 0,2 ][ 1,2 ][ 2,2 ]
[-2,1 ][-1,1 ][ 0,1 ][ 1,1 ][ 2,1 ]
[-2,0 ][-1,0 ][ 0,0 ][ 1,0 ][ 2,0 ]
[-2,-1][-1,-1][ 0,-1][ 1,-1][ 2,-1]
[-2,-2][-1,-2][ 0,-2][ 1,-2][ 2,-2]
If given n
, how to calculate the coordinates?
Here's a short and sweet answer using just simple math in pseudocode. No conditionals and no iteration. Given tileNum
for the tile number:
intRoot=int(sqrt(tileNum));
x=(round(intRoot/2)*(-1^(intRoot+1)))+((-1^(intRoot+1))*(((intRoot*(intRoot+1))-tileNum)-abs((intRoot*(intRoot+1))-tileNum))/2);
y=(round(intRoot/2)*(-1^intRoot))+((-1^(intRoot+1))*(((intRoot*(intRoot+1))-tileNum)+abs((intRoot*(intRoot+1))-tileNum))/2);
Here's a fiddle to see it in action.
Here is an code in JavaScript. It calculates position for 2D matrix starting with number 1 in a middle (0, 0)
13 12 11 10 25
14 3 2 9 24
15 4 1 8 23
16 5 6 7 22
17 18 19 20 21
/**
* Finds coordinates (position) of the number
*
* @param {Number} n - number to find position/coordinates for
* @return {Number[]} - x and y coordinates of the number
*/
function position(n) {
const k = Math.ceil((Math.sqrt(n) - 1) / 2);
let t = 2 * k + 1;
let m = Math.pow(t, 2);
t -= 1;
if (n >= m - t) {
return [k - (m - n), -k];
}
m -= t;
if (n >= m - t) {
return [-k, -k + (m - n)];
}
m -= t;
if (n >= m - t) {
return [-k + (m - n), k];
}
return [k, k - (m - n - t)];
}
First, find out which ring your desired element is in (hint: until you get to the outer ring, your spiral is made up of nested squares), then which side (of the 4) it is on, then you're just left with its position on that side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With