Calculate a ID for a cell based on x and y
I'm calculating a ID for a grid cell like this:
id = x * 65536 + y;
Trying to calculate x and y for a ID I do this:
x = id / 65536;
y开发者_如何学Go = id - (x * 65536);
This works, as long as Y is bigger than 0. If Y is negative, I have to calculate it like this:
x = (int)Math.Ceiling((double)id / 65536.0);
y = id - (x * 65536);
How do I know if I have to round up or down before knowing what y is? Is there a better way to generate one ID for a cell based on x and y? I feel like I'm missing something obvious, but after hours of tracking down strange errors to rounding problems, my brain is not working.
If you know that 30,000 > y > -30,000, you could do this:
x = (id + 30000) / 65536
y = id - (x * 65536)
If 65536 > y > -65536 then:
id = x * 131072 + y
x = (id + 65536) / 131072
y = id - (x * 131702)
You said in the comments that y can take a value from -65336 to 655536. In that case you should use:
id = x * 131072 + y; // 131072 = 2^17
For otherwise let, id be 100000, then this could be translated to two different coordinates:
100000 == 1 * 65536 + 34464 // x = 1, y = 34464
100000 == 2 * 65536 - 31072 // x = 2, y = -31072
So if the range of y is -65536 up to and including 65535, then you should use
id = x * 131072 + y;
and to convert back, you should use the solution that grc proposed:
x = (id + 65536) / 131072;
y = id - (x * 131072);
If C# has modulo (presumably the %
operator), use that. (I'm assuming x and y are integers.)
Are you looking for this?
UInt16 x = 123;
UInt16 y = 456;
UInt32 Point;
// encode y high, x low
Point = (UInt32)(x | (y << 0x10));
// decode
x = (UInt16)(Point & 0x0000FFFF);
y = (UInt16)((Point & 0xFFFF0000) >> 0x10);
精彩评论