예제 #1
0
파일: Coord.cs 프로젝트: neur0nid/OrbitsNet
        /// <summary>
        /// Creates a new instance of the class given XYZ coordinates.
        /// </summary>
        private Geo(Vector pos, double theta)
        {
            theta = theta % Globals.TwoPi;

             if (theta < 0.0)
             {
            // "wrap" negative modulo
            theta += Globals.TwoPi;
             }

             double r = Math.Sqrt(Globals.Sqr(pos.X) + Globals.Sqr(pos.Y));
             double e2 = Globals.F * (2.0 - Globals.F);
             double lat = Globals.AcTan(pos.Z, r);

             const double DELTA = 1.0e-07;
             double phi;
             double c;

             do
             {
            phi = lat;
            c = 1.0 / Math.Sqrt(1.0 - e2 * Globals.Sqr(Math.Sin(phi)));
            lat = Globals.AcTan(pos.Z + Globals.Xkmper * c * e2 * Math.Sin(phi), r);
             }
             while (Math.Abs(lat - phi) > DELTA);

             LatitudeRad  = lat;
             LongitudeRad = theta;
             Altitude = (r / Math.Cos(lat)) - Globals.Xkmper * c;
        }
예제 #2
0
파일: Eci.cs 프로젝트: cins/TrackLib.NetMF
 /// <summary>
 /// Creates a new instance of the class with the given position and
 /// velocity components.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 public Eci(Vector pos, Vector vel, Julian date, bool IsAeUnits)
 {
    Position = pos;
    Velocity = vel;
    jDate = date;
    Units = (IsAeUnits ? VectorUnits.Ae : VectorUnits.None);
 }
예제 #3
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));
        }
예제 #4
0
 /// <summary>
 /// Creates a new instance of the class with the given position and
 /// velocity components.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 public Eci(Vector pos, Vector vel)
 {
    Position = pos;
    Velocity = vel;
 }
예제 #5
0
 /// <summary>
 /// Creates a new instance of the class from XYZ coordinates.
 /// </summary>
 /// <param name="pos">The XYZ coordinates.</param>
 public Eci(Vector pos)
    : this(pos, new Vector())
 {
 }
예제 #6
0
 /// <summary>
 /// Creates an instance of the class with the given position, velocity, and time.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 /// <param name="date">The time associated with the position.</param>
 public EciTime(Vector pos, Vector vel, Julian date)
    : base(pos, vel)
 {
    Date = date;
 }
예제 #7
0
        // /////////////////////////////////////////////////////////////////////
        protected EciTime FinalPosition(double  incl, double omega,  double     e,   
                                      double     a, double    xl,  double xnode, 
                                      double    xn, double tsince)
        {
            if ((e * e) > 1.0)
             {
            throw new PropagationException("Error in satellite data");
             }

             double beta = Math.Sqrt(1.0 - e * e);

             // Long period periodics
             double axn  = e * Math.Cos(omega);
             double temp = 1.0 / (a * beta * beta);
             double xll  = temp * m_xlcof * axn;
             double aynl = temp * m_aycof;
             double xlt  = xl + xll;
             double ayn  = e * Math.Sin(omega) + aynl;

             // Solve Kepler's Equation
             double capu   = Globals.Fmod2p(xlt - xnode);
             double temp2  = capu;
             double temp3  = 0.0;
             double temp4  = 0.0;
             double temp5  = 0.0;
             double temp6  = 0.0;
             double sinepw = 0.0;
             double cosepw = 0.0;
             bool   fDone  = false;

             for (int i = 1; (i <= 10) && !fDone; i++)
             {
            sinepw = Math.Sin(temp2);
            cosepw = Math.Cos(temp2);
            temp3 = axn * sinepw;
            temp4 = ayn * cosepw;
            temp5 = axn * cosepw;
            temp6 = ayn * sinepw;

            double epw = (capu - temp4 + temp3 - temp2) /
                         (1.0 - temp5 - temp6) + temp2;

            if (Math.Abs(epw - temp2) <= 1.0e-06)
            {
               fDone = true;
            }
            else
            {
               temp2 = epw;
            }
             }

             // Short period preliminary quantities
             double ecose = temp5 + temp6;
             double esine = temp3 - temp4;
             double elsq  = axn * axn + ayn * ayn;
             temp  = 1.0 - elsq;
             double pl = a * temp;
             double r  = a * (1.0 - ecose);
             double temp1 = 1.0 / r;
             double rdot  = Globals.Xke * Math.Sqrt(a) * esine * temp1;
             double rfdot = Globals.Xke * Math.Sqrt(pl) * temp1;
             temp2 = a * temp1;
             double betal = Math.Sqrt(temp);
             temp3 = 1.0 / (1.0 + betal);
             double cosu  = temp2 * (cosepw - axn + ayn * esine * temp3);
             double sinu  = temp2 * (sinepw - ayn - axn * esine * temp3);
             double u     = Globals.AcTan(sinu, cosu);
             double sin2u = 2.0 * sinu * cosu;
             double cos2u = 2.0 * cosu * cosu - 1.0;

             temp  = 1.0 / pl;
             temp1 = Globals.Ck2 * temp;
             temp2 = temp1 * temp;

             // Update for short periodics
             double rk = r * (1.0 - 1.5 * temp2 * betal * m_x3thm1) +
                     0.5 * temp1 * m_x1mth2 * cos2u;
             double uk = u - 0.25 * temp2 * m_x7thm1 * sin2u;
             double xnodek = xnode + 1.5 * temp2 * m_cosio * sin2u;
             double xinck  = incl + 1.5 * temp2 * m_cosio * m_sinio * cos2u;
             double rdotk  = rdot - xn * temp1 * m_x1mth2 * sin2u;
             double rfdotk = rfdot + xn * temp1 * (m_x1mth2 * cos2u + 1.5 * m_x3thm1);

             // Orientation vectors
             double sinuk  = Math.Sin(uk);
             double cosuk  = Math.Cos(uk);
             double sinik  = Math.Sin(xinck);
             double cosik  = Math.Cos(xinck);
             double sinnok = Math.Sin(xnodek);
             double cosnok = Math.Cos(xnodek);
             double xmx = -sinnok * cosik;
             double xmy = cosnok * cosik;
             double ux  = xmx * sinuk + cosnok * cosuk;
             double uy  = xmy * sinuk + sinnok * cosuk;
             double uz  = sinik * sinuk;
             double vx  = xmx * cosuk - cosnok * sinuk;
             double vy  = xmy * cosuk - sinnok * sinuk;
             double vz  = sinik * cosuk;

             // Position
             double x = rk * ux;
             double y = rk * uy;
             double z = rk * uz;

             Vector vecPos = new Vector(x, y, z);
             DateTime gmt = Orbit.EpochTime.AddMinutes(tsince);

             // Validate on altitude
             double altKm = (vecPos.Magnitude() * (Globals.Xkmper / Globals.Ae));

             if (altKm < Globals.Xkmper)
             {
            throw new DecayException(gmt, Orbit.SatNameLong);
             }

             // Velocity
             double xdot = rdotk * ux + rfdotk * vx;
             double ydot = rdotk * uy + rfdotk * vy;
             double zdot = rdotk * uz + rfdotk * vz;

             Vector vecVel = new Vector(xdot, ydot, zdot);

             return new EciTime(vecPos, vecVel, new Julian(gmt));
        }
예제 #8
0
 /// <summary>
 /// Subtracts a vector from this vector.
 /// </summary>
 /// <param name="vec">The vector to subtract.</param>
 public void Sub(Vector vec)
 {
    X -= vec.X;
    Y -= vec.Y;
    Z -= vec.Z;
    W -= vec.W;
 }
예제 #9
0
 /// <summary>
 /// Creates a new vector from an existing vector.
 /// </summary>
 /// <param name="v">The existing vector to copy.</param>
 public Vector(Vector v)
    :this(v.X, v.Y, v.Z, v.W)
 {
 }
예제 #10
0
파일: Eci.cs 프로젝트: cins/TrackLib.NetMF
 /// <summary>
 /// Creates an instance of the class with the given position, velocity, and time.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 /// <param name="date">The time associated with the position.</param>
 public EciTime(Vector pos, Vector vel, Julian date, bool IsAeUnits)
    : base(pos, vel, date, IsAeUnits)
 {
    Date = date;
 }
예제 #11
0
 /// <summary>
 /// Calculates the dot product of this vector and another.
 /// </summary>
 /// <param name="vec">The second vector.</param>
 /// <returns>The dot product.</returns>
 public double Dot(Vector vec) => (X * vec.X) + (Y * vec.Y) + (Z * vec.Z);
예제 #12
0
 /// <summary>
 /// Calculates the angle, in radians, between this vector and another.
 /// </summary>
 /// <param name="vec">The second vector.</param>
 /// <returns>
 /// The angle between the two vectors, in radians.
 /// </returns>
 public double Angle(Vector vec) => Math.Acos(Dot(vec) / (Magnitude() * vec.Magnitude()));
예제 #13
0
 /// <summary>
 /// Calculates the dot product of this vector and another.
 /// </summary>
 /// <param name="vec">The second vector.</param>
 /// <returns>The dot product.</returns>
 public double Dot(Vector vec)
 {
    return (X * vec.X) + (Y * vec.Y) + (Z * vec.Z);
 }
예제 #14
0
파일: Eci.cs 프로젝트: cins/TrackLib.NetMF
 /// <summary>
 /// Creates a new instance of the class from XYZ coordinates.
 /// </summary>
 /// <param name="pos">The XYZ coordinates.</param>
 public Eci(Vector pos)
    : this(pos, new Vector(), new Julian(), false)
 {
 }
예제 #15
0
 /// <summary>
 /// Creates a new instance of the class from ECI coordinates.
 /// </summary>
 /// <param name="eci">The ECI coordinates.</param>
 public Eci(Eci eci)
 {
    Position = new Vector(eci.Position);
    Velocity = new Vector(eci.Velocity);
 }
예제 #16
0
파일: Site.cs 프로젝트: cins/TrackLib.NetMF
      /// <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  = GetPosition(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.m_El += Globals.ToRadians((1.02 / 
                                    Math.Tan(Globals.ToRadians(Globals.ToDegrees(el) + 10.3 / 
                                    (Globals.ToDegrees(el) + 5.11)))) / 60.0);
      if (topo.m_El < 0.0)
      {
         topo.m_El = el;    // Reset to true elevation
      }

      if (topo.m_El > (Globals.PI / 2))
      {
         topo.m_El = (Globals.PI / 2);
      }
#endif
         return topo;
      }
예제 #17
0
 /// <summary>
 /// Calculates the distance between two vectors as points in XYZ space.
 /// </summary>
 /// <param name="vec">The second vector.</param>
 /// <returns>The calculated distance.</returns>
 public double Distance(Vector vec) => Math.Sqrt(Math.Pow(X - vec.X, 2.0) +
          Math.Pow(Y - vec.Y, 2.0) +
          Math.Pow(Z - vec.Z, 2.0));