You can do 

 a >= b ? a * a + a + b : a + b * b

[taken from here][1].

That works for points in positive plane. If your coordinates can be in negative axis too, then you will have to do:

 A = a >= 0 ? 2 * a : -2 * a - 1;
 B = b >= 0 ? 2 * b : -2 * b - 1;
 A >= B ? A * A + A + B : A + B * B;

But to restrict the output to `uint` you will have to keep an upper bound for your inputs. and if so, then it turns out that you know the bounds. In other words in programming its impractical to write a function without having an idea on the integer type your inputs and output can be and if so there definitely will be a lower bound and upper bound for every integer type.

 public uint GetHashCode(whatever a, whatever b)
 {
 if (a > ushort.MaxValue || b > ushort.MaxValue || 
 a < ushort.MinValue || b < ushort.MinValue)
 { 
 throw new ArgumentOutOfRangeException();
 }

 return (uint)(a * short.MaxValue + b); //very good space/speed efficiency
 //or whatever your function is.
 }

If you want output to be strictly `uint` for unknown range of inputs, then there will be reasonable amount of collisions depending upon that range. What I would suggest is to have a function that can overflow but *unchecked*. Emil's solution is great, in C#:

 return unchecked((uint)((a & 0xffff) << 16 | (b & 0xffff))); 

See https://stackoverflow.com/questions/919612/mapping-two-integers-to-one-in-a-unique-and-deterministic-way for a plethora of options..

 [1]: http://szudzik.com/ElegantPairing.pdf