Example #1
0
        /// <summary>
        /// Encodes a coordinate on the sphere to the corresponding icosahedral face and
        /// containing 2D hex coordinates relative to that face center.
        /// </summary>
        /// <param name="res">The desired H3 resolution for the encoding.</param>
        /// <param name="face">The icosahedral face containing the spherical coordinates.</param>
        /// <returns>The 2D hex coordinates of the cell containing the point.</returns>
        public Vec2d ToHex2d(int res, int face)
        {
            var v = new Vec2d();

            var v3d = this.ToVec3d();

            // determine the icosahedron face
            face = 0;
            double sqd = Vec3d._pointSquareDist(FaceIJK.faceCenterPoint[0], v3d);

            for (int f = 1; f < NUM_ICOSA_FACES; f++)
            {
                double sqdT = Vec3d._pointSquareDist(FaceIJK.faceCenterPoint[f], v3d);
                if (sqdT < sqd)
                {
                    face = f;
                    sqd  = sqdT;
                }
            }

            // cos(r) = 1 - 2 * sin^2(r/2) = 1 - 2 * (sqd / 4) = 1 - sqd/2
            double r = Math.Acos(1 - sqd / 2);

            if (r < EPSILON)
            {
                v.x = v.y = 0.0;
                return(v);
            }

            // now have face and r, now find CCW theta from CII i-axis
            double theta = PositiveAngleRadians(FaceIJK.faceAxesAzRadsCII[face][0] - PositiveAngleRadians(GeoCoord._geoAzimuthRads(FaceIJK.faceCenterGeo[face], this)));

            // adjust theta for Class III (odd resolutions)
            if (H3Index.isResClassIII(res))
            {
                theta = PositiveAngleRadians(theta - M_AP7_ROT_RADS);
            }

            // perform gnomonic scaling of r
            r = Math.Tan(r);

            // scale for current resolution length u
            r /= RES0_U_GNOMONIC;
            for (int i = 0; i < res; i++)
            {
                r *= M_SQRT7;
            }

            // we now have (r, theta) in hex2d with theta ccw from x-axes

            // convert to local x,y
            v.x = r * Math.Cos(theta);
            v.y = r * Math.Sin(theta);

            return(v);
        }