Пример #1
0
      /// <summary>
      /// Creates a instance of the class from geodetic coordinates.
      /// </summary>
      /// <param name="geo">The geocentric coordinates.</param>
      /// <param name="date">The Julian date.</param>
      /// <remarks>
      /// Assumes the Earth is an oblate spheroid.
      /// Reference: The 1992 Astronomical Almanac, page K11
      /// Reference: www.celestrak.com (Dr. T.S. Kelso)
      /// </remarks>
      public Eci(Geo geo, Julian date)
      {
         double lat = geo.LatitudeRad;
         double lon = geo.LongitudeRad;
         double alt = geo.Altitude;

         // Calculate Local Mean Sidereal Time (theta)
         double theta = date.ToLmst(lon);
         double c = 1.0 / Math.Sqrt(1.0 + Globals.F * (Globals.F - 2.0) *
                          Globals.Sqr(Math.Sin(lat)));
         double s = Globals.Sqr(1.0 - Globals.F) * c;
         double achcp = (Globals.Xkmper * c + alt) * Math.Cos(lat);

         Position = new Vector();

         Position.X = achcp * Math.Cos(theta);             // km
         Position.Y = achcp * Math.Sin(theta);             // km
         Position.Z = (Globals.Xkmper * s + alt) * Math.Sin(lat);   // km
         Position.W = Math.Sqrt(Globals.Sqr(Position.X) +
                                Globals.Sqr(Position.Y) +
                                Globals.Sqr(Position.Z));  // range, km

         Velocity = new Vector();
         double mfactor = Globals.TwoPi * (Globals.OmegaE / Globals.SecPerDay);

         Velocity.X = -mfactor * Position.Y;               // km / sec
         Velocity.Y =  mfactor * Position.X;               // km / sec
         Velocity.Z = 0.0;                                 // km / sec
         Velocity.W = Math.Sqrt(Globals.Sqr(Velocity.X) +  // range rate km/sec^2
                                Globals.Sqr(Velocity.Y));
      }
Пример #2
0
        /// <summary>
        /// Creates a instance of the class from geodetic coordinates.
        /// </summary>
        /// <param name="geo">The geocentric coordinates.</param>
        /// <param name="date">The Julian date.</param>
        /// <remarks>
        /// Assumes the Earth is an oblate spheroid.
        /// Reference: The 1992 Astronomical Almanac, page K11
        /// Reference: www.celestrak.com (Dr. T.S. Kelso)
        /// </remarks>
        public Eci(Geo geo, Julian date)
        {
            double lat = geo.LatitudeRad;
            double lon = geo.LongitudeRad;
            double alt = geo.Altitude;

            // Calculate Local Mean Sidereal Time (theta)
            double theta = date.ToLmst(lon);
            double c     = 1.0 / Math.Sqrt(1.0 + Globals.F * (Globals.F - 2.0) *
                                           Globals.Sqr(Math.Sin(lat)));
            double s     = Globals.Sqr(1.0 - Globals.F) * c;
            double achcp = (Globals.Xkmper * c + alt) * Math.Cos(lat);

            Position = new Vector();

            Position.X = achcp * Math.Cos(theta);                    // km
            Position.Y = achcp * Math.Sin(theta);                    // km
            Position.Z = (Globals.Xkmper * s + alt) * Math.Sin(lat); // km
            Position.W = Math.Sqrt(Globals.Sqr(Position.X) +
                                   Globals.Sqr(Position.Y) +
                                   Globals.Sqr(Position.Z)); // range, km

            Velocity = new Vector();
            double mfactor = Globals.TwoPi * (Globals.OmegaE / Globals.SecPerDay);

            Velocity.X = -mfactor * Position.Y;              // km / sec
            Velocity.Y = mfactor * Position.X;               // km / sec
            Velocity.Z = 0.0;                                // km / sec
            Velocity.W = Math.Sqrt(Globals.Sqr(Velocity.X) + // range rate km/sec^2
                                   Globals.Sqr(Velocity.Y));
        }
Пример #3
0
        /// <summary>
        /// Returns the topo-centric (azimuth, elevation, etc.) coordinates for
        /// a target object described by the given ECI coordinates.
        /// </summary>
        /// <param name="eci">The ECI coordinates of the target object.</param>
        /// <returns>The look angle to the target object.</returns>
        public TopoTime GetLookAngle(EciTime eci)
        {
            // Calculate the ECI coordinates for this Site object at the time
            // of interest.
            Julian  date      = eci.Date;
            EciTime eciSite   = PositionEci(date);
            Vector  vecRgRate = new Vector(eci.Velocity.X - eciSite.Velocity.X,
                                           eci.Velocity.Y - eciSite.Velocity.Y,
                                           eci.Velocity.Z - eciSite.Velocity.Z);

            double x = eci.Position.X - eciSite.Position.X;
            double y = eci.Position.Y - eciSite.Position.Y;
            double z = eci.Position.Z - eciSite.Position.Z;
            double w = Math.Sqrt(Globals.Sqr(x) + Globals.Sqr(y) + Globals.Sqr(z));

            Vector vecRange = new Vector(x, y, z, w);

            // The site's Local Mean Sidereal Time at the time of interest.
            double theta = date.ToLmst(LongitudeRad);

            double sin_lat   = Math.Sin(LatitudeRad);
            double cos_lat   = Math.Cos(LatitudeRad);
            double sin_theta = Math.Sin(theta);
            double cos_theta = Math.Cos(theta);

            double top_s = sin_lat * cos_theta * vecRange.X +
                           sin_lat * sin_theta * vecRange.Y -
                           cos_lat * vecRange.Z;
            double top_e = -sin_theta * vecRange.X +
                           cos_theta * vecRange.Y;
            double top_z = cos_lat * cos_theta * vecRange.X +
                           cos_lat * sin_theta * vecRange.Y +
                           sin_lat * vecRange.Z;
            double az = Math.Atan(-top_e / top_s);

            if (top_s > 0.0)
            {
                az += Globals.Pi;
            }

            if (az < 0.0)
            {
                az += 2.0 * Globals.Pi;
            }

            double el   = Math.Asin(top_z / vecRange.W);
            double rate = (vecRange.X * vecRgRate.X +
                           vecRange.Y * vecRgRate.Y +
                           vecRange.Z * vecRgRate.Z) / vecRange.W;

            TopoTime topo = new TopoTime(az,         // azimuth, radians
                                         el,         // elevation, radians
                                         vecRange.W, // range, km
                                         rate,       // rate, km / sec
                                         eci.Date);

#if WANT_ATMOSPHERIC_CORRECTION
            // Elevation correction for atmospheric refraction.
            // Reference:  Astronomical Algorithms by Jean Meeus, pp. 101-104
            // Note:  Correction is meaningless when apparent elevation is below horizon
            topo.ElevationRad += Globals.ToRadians((1.02 /
                                                    Math.Tan(Globals.ToRadians(Globals.ToDegrees(el) + 10.3 /
                                                                               (Globals.ToDegrees(el) + 5.11)))) / 60.0);
            if (topo.ElevationRad < 0.0)
            {
                topo.ElevationRad = el; // Reset to true elevation
            }

            if (topo.ElevationRad > (Math.PI / 2.0))
            {
                topo.ElevationRad = (Math.PI / 2.0);
            }
#endif
            return(topo);
        }