Example #1
0
        /// <summary>
        /// Convert a latitude and longitude into Cartesian coordinates
        /// </summary>
        /// <param name="lon">Geodetic longitude in radians</param>
        /// <param name="lat">Geodetic latitude in radians</param>
        /// <param name="geodeticHeight">Above ellipsoid in metres</param>
        /// <returns>Cartesian position on the spheriod in metres</returns>
        public DVec3 ToVector(double lon, double lat, double geodeticHeight)
        {
            //work out normal position on surface of unit sphere using Euler formula and lat/lon
            //The latitude in this case is a geodetic latitude, so it's defined as the angle between the equatorial plane and the surface normal.
            //This is why the following works.
            double CosLat = Math.Cos(lat);
            DVec3  n      = new DVec3(CosLat * Math.Cos(lon), CosLat * Math.Sin(lon), Math.Sin(lat));
            //so (nx,ny,nz) is the geodetic surface normal i.e. the normal to the surface at lat,lon

            //using |ns|=gamma * ns, find gamma ( where |ns| is normalised ns)
            //with ns=Xs/a^2 i + Ys/b^2 j + Zs/c^2 k
            //equation of ellipsoid Xs^2/a^2 + Ys^2/b^2 + Zs^2/c^2 = 1
            //So, basically, I've got two equations for the geodetic surface normal that are related by a linear factor gamma

            DVec3 k = new DVec3(a2, b2, c2);

            k = k * n;

            double gamma    = Math.Sqrt(k.x * n.x + k.y * n.y + k.z * n.z);
            DVec3  rSurface = new DVec3(k.x / gamma, k.y / gamma, k.z / gamma);

            //NOTE: you do rSurface = rSurface + (geodetic.height * n) to add the height on if you need it
            rSurface = rSurface + new DVec3(geodeticHeight * n.x, geodeticHeight * n.y, geodeticHeight * n.z);

            //Relative to Centre rendering:
            rSurface.x -= CX; rSurface.y -= CY; rSurface.z -= CZ;

            return(rSurface);
        }
Example #2
0
        /// <summary>
        /// Convert a point on the surface of the ellipsoid into the Geodetic surface normal at that point
        /// </summary>
        DVec3 GeodeticSurfaceNormal(DVec3 P)
        {
            DVec3 Normal = new DVec3(P.x * ra2, P.y * rb2, P.z * rc2);

            Normal = DVec3.normalize(Normal);
            return(Normal);
        }
Example #3
0
        /// <summary>
        /// Scale a geocentric point to the surface of the ellipsoid (along the geocentric normal)
        /// </summary>
        DVec3 ScaleToGeocentricSurface(DVec3 P)
        {
            double beta = 1.0 / Math.Sqrt(
                (P.x * P.x) * ra2 +
                (P.y * P.y) * rb2 +
                (P.z * P.z) * rc2
                );

            return(beta * P);
        }
Example #4
0
        /// <summary>
        /// Cozzi and Ring method using Newton Raphson from 3D Engine Design for Virtual Globes book
        /// </summary
        DVec3 ScaleToGeodeticSurface(DVec3 P)
        {
            double beta = 1.0 / Math.Sqrt(
                (P.x * P.x) * ra2 +
                (P.y * P.y) * rb2 +
                (P.z * P.z) * rc2
                );
            double n     = DVec3.length(new DVec3(beta * P.x * ra2, beta * P.y * rb2, beta * P.z * rc2));
            double alpha = (1.0 - beta) * (DVec3.length(P) / n);

            double x2 = P.x * P.x;
            double y2 = P.y * P.y;
            double z2 = P.z * P.z;

            double da   = 0.0;
            double db   = 0.0;
            double dc   = 0.0;
            double s    = 0.0;
            double dSdA = 1.0;

            do
            {
                alpha -= (s / dSdA);
                da     = 1.0 + (alpha * ra2);
                db     = 1.0 + (alpha * rb2);
                dc     = 1.0 + (alpha * rc2);

                double da2 = da * da;
                double db2 = db * db;
                double dc2 = dc * dc;

                double da3 = da * da2;
                double db3 = db * db2;
                double dc3 = dc * dc2;

                s = x2 / (a2 * da2) + y2 / (b2 * db2) + z2 / (c2 * dc2) - 1.0;

                dSdA = -2.0 * (x2 / (a4 * da3) + y2 / (b4 * db3) + z2 / (c4 * dc3));
            } while (Math.Abs(s) > 1e-10);

            return(new DVec3(P.x / da, P.y / db, P.z / dc));
        }
Example #5
0
        /// <summary>
        /// Normalise the vector and return the unit vector pointing in the same direction
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static DVec3 normalize(DVec3 v)
        {
            double mag = DVec3.length(v);

            return(new DVec3(v.x / mag, v.y / mag, v.z / mag));
        }
Example #6
0
 /// <summary>
 /// Scalar length, or magnitude of vector
 /// </summary>
 /// <param name="v"></param>
 /// <returns>A double value which is the length along the vector</returns>
 public static double length(DVec3 v)
 {
     return(Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z));
 }