GML Q:mathematical problem

Z

zendraw

Guest
does any1 know a formula that can create a spiral out of a 2d grid? if not, does any1 know a mathematician who can make such a formula? i alredy have a function that creates the resaults, but i need it as a formula.
this is how the coords used in the function look, and the end resault.
 

jo-thijs

Member
does any1 know a formula that can create a spiral out of a 2d grid? if not, does any1 know a mathematician who can make such a formula? i alredy have a function that creates the resaults, but i need it as a formula.
this is how the coords used in the function look, and the end resault.
What do you mean with "I need it as a formula"?
Are you asking for a one-liner that describes a function f : R x R -> R : (x,y) |-> f(x,y)
that given the coordinates in your left picture returns the corresponding value in your right picture?
 
Z

zendraw

Guest
yes, i currently use a loop to generate the numbers in the 2nd grid and i want to remove that and use a 1liner. or simply put, generate them trough calculation and not brute force.
is that formula just an example or?
 

jo-thijs

Member
yes, i currently use a loop to generate the numbers in the 2nd grid and i want to remove that and use a 1liner. or simply put, generate them trough calculation and not brute force.
is that formula just an example or?
Well, it's not a one-liner, but this script should do:
Code:
///scr_spiral_at(x, y)
var X = argument0;
var Y = argument1;
var n = max(abs(X), abs(Y));
var m = (n + 1) * n * 4

if Y == -n
    return m - (n - X);
if X == -n
    return m - n * 2 - (n + Y);
if Y == n
    return m - n * 4 - (n + X);
return m - n * 6 - (n - Y);
You can test it by putting this code in a draw event:
Code:
for(i = 0; i < 10; i += 1)
for(j = 0; j < 10; j += 1)
    draw_text(i * 32 + 32, j * 32 + 32, scr_spiral_at(i - 4, j - 4));
 
Z

zendraw

Guest
i will test it in a while, can you explain the logic behind it? if it works its better then what i have and thank you.
 

jo-thijs

Member
i will test it in a while, can you explain the logic behind it? if it works its better then what i have and thank you.
You're welcome!

And sure, I can.
Let's call (the border of) a rectangle with as center the origin (0,0) a cycle of the spiral.
The n-th cycle is a rectangle with with vertices (-n, -n), (-n, n), (n, -n) and (n, n).
The n-th cycle then has 8*n amount of squares in itself, except for the zeroth cycle, which has exactly 1 square (0, 0).
You can verify this to be true by induction.
You know the first cycle has 8 squares.
The n-th cycle can be build by taking the (n-1)-th cycle, move its corners 1 square diagnally away from the origin,
by moving all the squares on the left edge 1 square to the left, by moving all the squares on the right edge 1 square to the right,
by moving all the squares on the top edge 1 square upwards and by moving all the squares on the bottom edge 1 square downwards.
You'll then always need 8 additional squares to complete the n-th cycle, so the n-th cycle contains 8 squares more than the (n-1)-th cycle.
This completes the proof by induction.

Now, we can prove that the value of the squares at positions (n, -n) equal the amount of squares in all k-th cycles with 0 < k < n + 1.
You can understand this as follows:
The square (n, -n) is the last square of the n-th cycle the spiral goes through.
Since the value of a square equals the amount of preceding squares on the spiral, ignoring the square (0, 0), we know the above is true.

So, now we want to know the sum of 8*k with 0 < k < n + 1.
This sum equals 8*(n(n+1)/2), which equals n*(n+1)*4.
This is what I calculated in the vars in my script.
n is such that (X, Y) is a square of the n-th cycle in te spiral.
m is the value of the last square in the n-th cycle.

Now, if we don't have square (n, -n), but we ave another square on the top edge of the cycle of the form (X, -n),
then we know that there are exactly n - X amount of squares between the last square of the cycle and the input square (including the input square, but excluding the last square).
Thus we know that the value of (X, -n) is m - (n - X).
This is what you see in my first if-statement and return-statement.

Now, suppose we have a square at the right edge of the cycle, of the form (-n, Y).
We know the value of (-n, -n), because it is a square at the top edge, so its value is m - (n - (-n)) = m - 2*n.
Similarly to last time, we know that there are exactly Y - (-n) amount of squares between (-n, Y) and (-n, -n),
so the value of (-n, Y) is m - 2*n - (Y + n).
This is exactly what I do in the second if-statement and return-statement.

Analogously, you can calculate the values of squares on the bottom and right edge of the cycle.
 
Z

zendraw

Guest
yea it does work,
i somewhat get the logic, i also noticed that every next square has 8 more squares. but does this work to infinity? i dont fully understand the formula, i will look at it more tomorrow, didnt have the time today. but yea, what is important to me is does it work to infinity?
 

jo-thijs

Member
yea it does work,
i somewhat get the logic, i also noticed that every next square has 8 more squares. but does this work to infinity? i dont fully understand the formula, i will look at it more tomorrow, didnt have the time today. but yea, what is important to me is does it work to infinity?
It's not tat every next square has 8 more, rather that every cycle has 8 more squares than the previous cycle.

Also, are you asking whether my script works for any pair of integers (X, Y)?
In that case, of course it does!
I gave the explenation as to why.
 
Z

zendraw

Guest
yea, i meant every new cycle.
yes, and yes i will check it out more to understand it, and thanks again, its very helpful.

PS: a question in my head that perhaps you can answer. with this method is it possible to find a value relative to another value? for isntance i have 16, can i find x-2, y-4 from that value? 16 with x-2,y-4 is 70.
 

jo-thijs

Member
yea, i meant every new cycle.
yes, and yes i will check it out more to understand it, and thanks again, its very helpful.

PS: a question in my head that perhaps you can answer. with this method is it possible to find a value relative to another value? for isntance i have 16, can i find x-2, y-4 from that value? 16 with x-2,y-4 is 70.
You're welcome!

And to the PS, that sure is possible!
Code:
///scr_spiral_relative(dx, dy, value)

var dx = argument0;
var dy = argument1;
var val = argument2;

var n = ceil(argument2 * 0.5 / (sqrt(argument2 + 1) + 1));
var m = (n + 1) * n * 4;

var X, Y;
switch (m - val) div (n * 2) {
case 0:
    X = n - (m - val);
    Y = -n;
    break;
case 1:
    X = -n;
    Y = ((m - n * 2) - val) - n;
    break;
case 2:
    X = ((m - n * 4) - val) - n;
    Y = n;
    break;
case 3:
    X = n;
    Y = n - ((m - n * 6) - val);
    break;
}

return scr_spiral_at(X + dx, Y + dy);
 
Top