コード例 #1
0
 public void Pow3Test()
 {
     for (int i = 0; i < 20; i++)
     {
         Assert.AreEqual(Pow3.Calc(i), (long)Math.Pow(3, i));
     }
 }
コード例 #2
0
ファイル: GeoHex.cs プロジェクト: pine/GeoHex.cs
        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));
        }
コード例 #3
0
ファイル: GeoHex.cs プロジェクト: naochang/GeoHex.cs
        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));
        }
コード例 #4
0
        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");
            }
        }
コード例 #5
0
ファイル: GeoHex.cs プロジェクト: pine/GeoHex.cs
 public static double CalcHexSize(int level)
 {
     return(h_base / Pow3.Calc(level + 3));
 }
コード例 #6
0
ファイル: GeoHex.cs プロジェクト: pine/GeoHex.cs
        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()));
        }
コード例 #7
0
ファイル: GeoHex.cs プロジェクト: pine/GeoHex.cs
        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);
        }