Ejemplo n.º 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="g">The spherical coordinates to encode.</param>
        /// <param name="res">The desired H3 resolution for the encoding.</param>
        /// <returns>
        /// Tuple
        /// Item1: The resulting face
        /// Item2: The 2D hex coordinates of the cell containing the point.
        /// </returns>
        /// <!--
        /// faceijk.c
        /// void _geoToHex2d
        /// -->
        public static (int, Vec2d) ToHex2d(this GeoCoord g, int res)
        {
            var v3d = g.ToVec3d();

            var newFace = 0;

            // determine the icosahedron face
            decimal sqd = v3d.PointSquareDistance(Constants.FaceIjk.FaceCenterPoint[0]);

            for (var f = 1; f < Constants.H3.NUM_ICOSA_FACES; f++)
            {
                decimal sqdT = v3d.PointSquareDistance(Constants.FaceIjk.FaceCenterPoint[f]);
                if (!(sqdT < sqd))
                {
                    continue;
                }
                newFace = f;
                sqd     = sqdT;
            }

            // cos(r) = 1 - 2 * sin^2(r/2) = 1 - 2 * (sqd / 4) = 1 - sqd/2
            decimal r = DecimalEx.ACos(1 - sqd / 2.0m);

            if (r < Constants.H3.EPSILON)
            {
                return(newFace, new Vec2d());
            }
            // now have face and r, now find CCW theta from CII i-axis
            decimal theta =
                (
                    Constants.FaceIjk.FaceAxesAzRadsCii[newFace, 0] -
                    Constants.FaceIjk.FaceCenterGeo[newFace].AzimuthRadiansTo(g)
                    .NormalizeRadians()
                ).NormalizeRadians();

            // adjust theta for Class III (odd resolutions)
            if (res.IsResClassIii())
            {
                theta = (theta - Constants.H3.M_AP7_ROT_RADS).NormalizeRadians();
            }

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

            // scale for current resolution length u
            r /= Constants.H3.RES0_U_GNOMONIC;
            for (var i = 0; i < res; i++)
            {
                r *= Constants.FaceIjk.MSqrt7;
            }

            // we now have (r, theta) in hex2d with theta ccw from x-axes
            // convert to local x,y
            return(newFace,
                   new Vec2d
                   (
                       r * DecimalEx.Cos(theta),
                       r * DecimalEx.Sin(theta)
                   ));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Surface area in radians^2 of spherical triangle on unit sphere.
        ///
        /// For the math, see:
        /// https://en.wikipedia.org/wiki/Spherical_trigonometry#Area_and_spherical_excess
        /// </summary>
        /// <param name="a">length of triangle side A in radians</param>
        /// <param name="b">length of triangle side B in radians</param>
        /// <param name="c">length of triangle side C in radians</param>
        /// <returns>area in radians^2 of triangle on unit sphere</returns>
        /// <!--
        /// geoCoord.c
        /// double triangleEdgeLengthsToArea
        /// -->
        private static decimal TriangleEdgeLengthToArea(decimal a, decimal b, decimal c)
        {
            decimal s = (a + b + c) / 2;

            a  = (s - a) / 2;
            b  = (s - b) / 2;
            c  = (s - c) / 2;
            s /= 2;

            return(4 * DecimalEx.ATan
                       (DecimalEx.Sqrt(DecimalEx.Tan(s) *
                                       DecimalEx.Tan(a) *
                                       DecimalEx.Tan(b) *
                                       DecimalEx.Tan(c))));
        }
Ejemplo n.º 3
0
        public void findTan()
        {
            Console.Write("Enter the number:\n");
            string stringConversions = Console.ReadLine();

            if (stringConversions.Contains("/"))
            {
                Fract.Fraction(stringConversions);
                FractionConverted = Fract.Fraction(stringConversions);
                Answer            = DecimalEx.Tan(decimalConverted);
                Console.WriteLine($"Your answer is {Answer}.\n");
            }
            else
            {
                decimalConverted = Decimal.Parse(stringConversions);
                Answer           = DecimalEx.Tan(decimalConverted);
                Console.WriteLine($"Your answer is {Answer}.\n");
            }
        }