public void Pow3Test() { for (int i = 0; i < 20; i++) { Assert.AreEqual(Pow3.Calc(i), (long)Math.Pow(3, i)); } }
public static XY AdjustXY(long x, long y, int level) { long max_hsteps = Pow3.Calc(level + 2); long hsteps = Math.Abs(x - y); if (hsteps == max_hsteps && x > y) { long tmp = x; x = y; y = tmp; } else if (hsteps > max_hsteps) { long diff = hsteps - max_hsteps; long diff_x = (long)Math.Floor((double)(diff / 2)); long diff_y = diff - diff_x; if (x > y) { long edge_x = x - diff_x; long edge_y = y + diff_y; long h_xy = edge_x; edge_x = edge_y; edge_y = h_xy; x = edge_x + diff_x; y = edge_y - diff_y; } else if (y > x) { long edge_x = x + diff_x; long edge_y = y - diff_y; long h_xy = edge_x; edge_x = edge_y; edge_y = h_xy; x = edge_x - diff_x; y = edge_y + diff_y; } } // XXX: check precision return(new XY(x, y)); }
public static XY AdjustXY(int x, int y, int level) { int max_hsteps = Pow3.Calc(level + 2); int hsteps = Math.Abs(x - y); if (x > y && hsteps == max_hsteps) { int tmp = x; x = y; y = tmp; } else if (hsteps > max_hsteps) { int diff = hsteps - max_hsteps; int diff_x = diff / 2; // (long) Math.Floor((double) (diff/2)); int diff_y = diff - diff_x; if (x > y) { int edge_x = x - diff_x; int edge_y = y + diff_y; int h_xy = edge_x; edge_x = edge_y; edge_y = h_xy; x = edge_x + diff_x; y = edge_y - diff_y; } else if (y > x) { int edge_x = x + diff_x; int edge_y = y - diff_y; int h_xy = edge_x; edge_x = edge_y; edge_y = h_xy; x = edge_x - diff_x; y = edge_y + diff_y; } } return(new XY(x, y)); }
public void Pow3Test() { const int MaxRepeat = 1000000; const int MaxLevel = 19; { TimeWatch.Reset(); TimeWatch.Resume(); for (int repeat = 0; repeat < MaxRepeat; repeat++) { for (int i = 0; i < MaxLevel; i++) { Pow3.Calc(i); } } TimeWatch.Pause(MaxLevel * MaxRepeat); TimeWatch.OutputResult("Pow3"); } { TimeWatch.Reset(); TimeWatch.Resume(); for (int repeat = 0; repeat < MaxRepeat; repeat++) { for (int i = 0; i < MaxLevel; i++) { Math.Pow(3, i); } } TimeWatch.Pause(MaxLevel * MaxRepeat); TimeWatch.OutputResult("Math.Pow3"); } }
public static double CalcHexSize(int level) { return(h_base / Pow3.Calc(level + 3)); }
public static Zone GetZoneByXY(double x, double y, int level) { double h_size = CalcHexSize(level); long h_x = (long)Math.Round(x); long h_y = (long)Math.Round(y); double unit_x = 6 * h_size; double unit_y = 6 * h_size * h_k; double h_lat = (h_k * h_x * unit_x + h_y * unit_y) / 2; double h_lon = (h_lat - h_y * unit_y) / h_k; Location z_loc = XY2Location(h_lon, h_lat); double z_loc_x = z_loc.longitude; double z_loc_y = z_loc.latitude; double max_hsteps = Pow3.Calc(level + 2); double hsteps = Math.Abs(h_x - h_y); if (hsteps == max_hsteps) { if (h_x > h_y) { long tmp = h_x; h_x = h_y; h_y = tmp; } z_loc_x = -180; } StringBuilder h_code = new StringBuilder(); List <int> code3_x = new List <int>(); List <int> code3_y = new List <int>(); long mod_x = h_x; long mod_y = h_y; for (int i = 0; i <= level + 2; i++) { long h_pow = Pow3.Calc(level + 2 - i); double h_pow_half = Math.Ceiling((double)h_pow / 2); if (mod_x >= h_pow_half) { code3_x.Add(2); mod_x -= h_pow; } else if (mod_x <= -h_pow_half) { code3_x.Add(0); mod_x += h_pow; } else { code3_x.Add(1); } if (mod_y >= h_pow_half) { code3_y.Add(2); mod_y -= h_pow; } else if (mod_y <= -h_pow_half) { code3_y.Add(0); mod_y += h_pow; } else { code3_y.Add(1); } if (i == 2 && (z_loc_x == -180 || z_loc_x >= 0)) { if (code3_x[0] == 2 && code3_y[0] == 1 && code3_x[1] == code3_y[1] && code3_x[2] == code3_y[2]) { code3_x[0] = 1; code3_y[0] = 2; } else if (code3_x[0] == 1 && code3_y[0] == 0 && code3_x[1] == code3_y[1] && code3_x[2] == code3_y[2]) { code3_x[0] = 0; code3_y[0] = 1; } } } for (int i = 0; i < code3_x.Count; i++) { // TODO: it's not good for memory efficient StringBuilder code3 = new StringBuilder(); StringBuilder code9 = new StringBuilder(); code3.Append("").Append(code3_x[i]).Append(code3_y[i]); code9.Append(StringToInt(code3.ToString(), 3)); h_code.Append(code9); } string h_2 = h_code.ToString().Substring(3); int h_1 = int.Parse(h_code.ToString().Substring(0, 3)); int h_a1 = (int)Math.Floor((double)h_1 / 30); int h_a2 = h_1 % 30; StringBuilder h_code_r = new StringBuilder(); h_code_r.Append(h_key[h_a1]).Append(h_key[h_a2]).Append(h_2.ToString()); return(new Zone(z_loc_y, z_loc_x, h_x, h_y, h_code_r.ToString())); }
private static XY GetXYByCode(string code) { int level = code.Length - 2; long h_x = 0; long h_y = 0; char[] codeChars = code.ToCharArray(); string h_dec9 = new StringBuilder("").Append( h_key.IndexOf(codeChars[0]) * 30 + h_key.IndexOf(codeChars[1]) ) .Append(code.Substring(2)) .ToString(); if (RegMatch(h_dec9[0], INC15) && RegMatch(h_dec9[1], EXC125) && RegMatch(h_dec9[2], EXC125)) { if (h_dec9[0] == '5') { h_dec9 = "7" + h_dec9.Substring(1, h_dec9.Length - 1); } else if (h_dec9[0] == '1') { h_dec9 = "3" + h_dec9.Substring(1, h_dec9.Length - 1); } } int d9xlen = h_dec9.Length; for (int i = 0; i < level + 3 - d9xlen; i++) { h_dec9 = "0" + h_dec9; d9xlen++; } StringBuilder h_dec3 = new StringBuilder(); for (int i = 0; i < d9xlen; i++) { int dec9i = int.Parse("" + h_dec9[i]); string h_dec0 = IntToString(dec9i, new char[] { '0', '1', '2' }); if (h_dec0.Length == 1) { h_dec3.Append("0"); } h_dec3.Append(h_dec0); } List <char> h_decx = new List <char>(); List <char> h_decy = new List <char>(); for (int i = 0; i < h_dec3.Length / 2; i++) { h_decx.Add(h_dec3[i * 2]); h_decy.Add(h_dec3[i * 2 + 1]); } for (int i = 0; i <= level + 2; i++) { long h_pow = Pow3.Calc(level + 2 - i); if (h_decx[i] == '0') { h_x -= h_pow; } else if (h_decx[i] == '2') { h_x += h_pow; } if (h_decy[i] == '0') { h_y -= h_pow; } else if (h_decy[i] == '2') { h_y += h_pow; } } XY inner_xy = AdjustXY(h_x, h_y, level); return(inner_xy); }