// /////////////////////////////////////////////////////////////////////
		// Calculate the angle between this vector and another
		public double Angle(Vector vec)
		{
			return Math.Acos(Dot(vec) / (Magnitude() * vec.Magnitude()));
		}
		// /////////////////////////////////////////////////////////////////////
		protected Eci FinalPosition(double  incl, double omega,  double     e,
			double     a, double    xl,  double xnode,
			double    xn, double tsince)
		{
			if ((e * e) > 1.0)
			{
				throw new Exception("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) <= Globals.E6A)
					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);

			// Validate on altitude
			double altKm = (vecPos.Magnitude() * (Globals.XKMPER / Globals.AE));

			if ((altKm < Globals.EARTH_RAD) || (altKm > (2 * Globals.GEOSYNC_ALT)))
			{
				throw new Exception("Satellite orbit may have decayed");
			}

			// 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);

			DateTime gmt = m_Orbit.EpochTime;

			gmt = gmt.AddMinutes(tsince);

			return new Eci(vecPos, vecVel, new Julian(gmt), true);
		}