Pattara Sukprasert
Aug 22, 2017 · 3 min read

Initially, my plan was to determine values along four segments of two axes, says, j = — i and — j = — i.

Then for each quadrant, I thought I would use one segment as a “base” and computed an “offset” from the base. It would look like this:

The good thing about this it that you can express the value of a point along these lines in one function

It turned out to be a mess as doing it this way produced edge cases along the axes.

To compromise that, I use only one line (two segments) as the base:

Still, another line is need to draw the boundary, so quadrant calculation is unavoidable.

The code to determine the quadrant of a given point looks like this:

// Axes are i = j and i = - j.
int get_quadrant(int i, int j) {
bool x_positive = (j - i) > 0;
bool y_positive = (i + j) > 0;
if ( !x_positive && !y_positive) return 3;
else if ( !x_positive && y_positive) return 2;
else if ( x_positive && y_positive) return 1;
else return 0;
}

And code to determine actual values:

int unspiral(int i, int j) {
int q = get_quadrant(i, j);
// x along line j = - i.
int x = max(abs(i), abs(j));
if (q >= 2) x = - x;
int base = (2 * x) * (2 * x) - (2 * x);
int offset;
if (q == 0) offset = x - j;
else if (q == 1) offset = i - x;
else if (q == 2) offset = j - x;
else offset = x + i;
return base - offset;
}

Frankly, I don’t like it that much. I hope there is a cleaner constructive way to create a spiral but I can’t come up with one yet, so I decide to post this one first.

Is it run in constant time? Yes. Is it easy to understand? I would say that this is easier to understand than the original one (at least to me). It might not be that easy to modify though.

Note that I have given some thoughts about using polar coordinate system. Even that, I’m convinced that distance calculation between points and the center is not negligible. Since it is the case, I encourage any programmer to point out this calculation in a separate line.

Since Thai posted an additional picture, which he used during his thought, let me take the space here to say that your choices of segments were elegant because two normal lines pointing out from your base segment wouldn’t be intersected.

P.S. I prefer (2 * x) * (2 * x) to 4 * x * x since it gives me a sense of scaling to a single number rather than a random multiplying factor.

P.S.2, I do not write this in JS and I feel guilty about it, but it shouldn’t make no different in terms of code understanding.

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade