예제 #1
0
LLPoint DestVincenty(LLPoint pt, double brng, double dist, double* revAz)
	{
		double s = dist;
		double alpha1 = brng;
		double sinAlpha1 = sin(alpha1);
		double cosAlpha1 = cos(alpha1);

		double tanU1 = (1.0 - Flattening()) * tan(pt.latitude);
		double cosU1 = 1.0 / sqrt((1.0 + tanU1*tanU1));
		double sinU1 = tanU1 * cosU1;
		double sigma1 = atan2(tanU1, cosAlpha1);
		double sinAlpha = cosU1 * sinAlpha1;
		double cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
		double uSq = cosSqAlpha * (SemiMajorAxis() * SemiMajorAxis() - SemiMinorAxis() * SemiMinorAxis()) /
                                  (SemiMinorAxis() * SemiMinorAxis());
		double A = 1.0 + uSq / 16384.0 * (4096.0 + uSq * (-768.0 + uSq * (320.0 - 175.0 * uSq)));
		double B = uSq / 1024.0 * (256.0 + uSq * (-128.0 + uSq * (74.0 - 47.0 * uSq)));

		double sigma = s / (SemiMinorAxis() * A);
		double sigmaP = M_2PI;
		double sinSigma = sin(sigma);
		double cosSigma = cos(sigma);
		double cos2SigmaM = cos(2.0 * sigma1 + sigma);
		int iterLimit = 0;
		while (fabs(sigma-sigmaP) > Eps() && ++iterLimit < 100) {
			cos2SigmaM = cos(2.0 * sigma1 + sigma);
			sinSigma = sin(sigma);
			cosSigma = cos(sigma);
			double cos2SigmaSq = cos2SigmaM * cos2SigmaM;
			double deltaSigma = B * sinSigma * (cos2SigmaM + B * 0.25 * (cosSigma * (-1.0 + 2.0 * cos2SigmaSq)-
				B / 6.0 * cos2SigmaM * (-3.0 + 4.0 * sinSigma * sinSigma) * (-3.0 + 4.0 * cos2SigmaSq)));

			sigmaP = sigma;
			sigma = s / (SemiMinorAxis() * A) + deltaSigma;
		}

		double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
		double lat2 = atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
			(1.0 - Flattening()) * sqrt(sinAlpha * sinAlpha + tmp * tmp));
		double lambda = atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
		double C = Flattening() / 16.0 * cosSqAlpha * (4.0 + Flattening() * (4.0 -3.0 * cosSqAlpha));
		double L = lambda - (1.0 - C) * Flattening() * sinAlpha *
			(sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM)));


    LLPoint return_value;
    return_value.latitude=lat2;
    return_value.longitude= pt.longitude + L;

    *revAz =atan2(sinAlpha, -tmp);
    return return_value;
	}
예제 #2
0
bool cOrbit::TrueAnomalyAtRadius(double r, double timeOfStart, double &tAOut) const
{
    double e = Eccentricity();
    double a = SemiMajorAxis();
    bool status = false;

    double arg = (a - a*e*e - r)/(e*r);

    if(-1 <= arg && arg <= 1)
    {
        double tA = TrueAnomalyAt(timeOfStart, status);

        tAOut = acos(arg);

        tAOut = min(
            fmod(tAOut - tA + 4*M_PI, 2*M_PI),
            fmod(-tAOut - tA + 4*M_PI, 2*M_PI)
            ) + tA;

        return status;
    }
    else
    {
        return false;
    }
}
예제 #3
0
Vector3d cOrbit::VelocityAtTrueAnomaly(double tA) const
{
    double mu = ReferenceBody().GravitationalParameter();
    double e = Eccentricity();
    double h = std::sqrt(mu * SemiMajorAxis() * (1.0 - e * e));
    double r = RadiusAtTrueAnomaly(tA);
    double sin = std::sin(tA);
    double cos = std::cos(tA);
    double vr = mu * e * sin / h;
    double vtA = h / r;
    return RotationToReferenceFrame()._transformVector(Vector3d(vr * cos - vtA * sin, vr * sin + vtA * cos, 0)); 
}
예제 #4
0
double cOrbit::PhaseAngle(cOrbit &orbit, double t, bool &status) const
{
    Vector3d n = NormalVector();
    Vector3d p1 = PositionAtTrueAnomaly(TrueAnomalyAt(t, status));
    Vector3d p2 = orbit.PositionAtTrueAnomaly(orbit.TrueAnomalyAt(t, status));
    p2 = p2 - (n * p2.dot(n)); // Project p2 onto our orbital plane
    double r1 = p1.norm();
    double r2 = p2.norm();

    double phaseAngle = std::acos(p1.dot(p2) / (r1 * r2));
    if(p1.cross(p2).dot(n) < 0.0)
    {
        phaseAngle = TWO_PI - phaseAngle;
    }

    if (orbit.SemiMajorAxis() < SemiMajorAxis())
    {
        phaseAngle = phaseAngle - TWO_PI;
    }

    return phaseAngle;
}
	double _stdcall PrimeVerticalCurvature( double dAngle )
	{
		return SemiMajorAxis() / sqrt(1.0 - eSq() * (sin(dAngle) * sin(dAngle)));
	}
예제 #6
0
	bool DistVincenty(LLPoint pt1, LLPoint pt2, InverseResult * result)
	{
		double L = pt2.longitude - pt1.longitude;
		double U1 = atan((1-Flattening()) * tan(pt1.latitude));
		double U2 = atan((1-Flattening()) * tan(pt2.latitude));

		double sinU1 = sin(U1);
		double cosU1 = cos(U1);
		double sinU2 = sin(U2);
		double cosU2 = cos(U2);

		double dCosU1CosU2 = cosU1 * cosU2;
		double dCosU1SinU2 = cosU1 * sinU2;

		double dSinU1SinU2 = sinU1 * sinU2;
		double dSinU1CosU2 = sinU1 * cosU2;


		double lambda = L;
		double lambdaP = M_2PI;
		int iterLimit = 0;
		double cosSqAlpha;
		double sinSigma;
		double cos2SigmaM;
		double cosSigma;
		double sigma;
		double sinAlpha;
		double C;
		double sinLambda, cosLambda;

		do {
			sinLambda = sin(lambda);
			cosLambda = cos(lambda);
			sinSigma = sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
				(dCosU1SinU2 - dSinU1CosU2 * cosLambda) * (dCosU1SinU2 - dSinU1CosU2 * cosLambda));

			if (sinSigma==0)
			{
				(*result).reverseAzimuth = 0.0;
				(*result).azimuth = 0.0;
				(*result).distance = 0.0;
				return true;
			}
			cosSigma = dSinU1SinU2 + dCosU1CosU2 * cosLambda;
			sigma = atan2(sinSigma, cosSigma);
			sinAlpha = dCosU1CosU2 * sinLambda / sinSigma;
			cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
			cos2SigmaM = cosSigma - 2.0 * dSinU1SinU2 / cosSqAlpha;

			if (!IsNumber(cos2SigmaM))
				cos2SigmaM = 0.0;  // equatorial line: cosSqAlpha=0 (§6)
			C = Flattening() / 16.0 * cosSqAlpha * (4.0 + Flattening() * (4.0 - 3.0 * cosSqAlpha));
			lambdaP = lambda;
			lambda = L + (1.0 - C) * Flattening() * sinAlpha *
				(sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1.0 + 2.0 * cos2SigmaM *cos2SigmaM)));
		} while (fabs(lambda-lambdaP) > Eps() && ++iterLimit < 100);

		double uSq = cosSqAlpha * (SemiMajorAxis() * SemiMajorAxis() - SemiMinorAxis() * SemiMinorAxis()) /
                                  (SemiMinorAxis() * SemiMinorAxis());
		double A = 1.0 + uSq / 16384.0 * (4096.0 + uSq * (-768.0 + uSq * (320.0 - 175.0 * uSq)));
		double B = uSq / 1024.0 * (256.0 + uSq * (-128.0 + uSq * (74.0 - 47.0 * uSq)));
		double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4.0 * (cosSigma * (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM)-
			B / 6.0 * cos2SigmaM * (-3.0 + 4.0 * sinSigma * sinSigma) * (-3.0 + 4.0 * cos2SigmaM * cos2SigmaM)));

		(*result).distance = SemiMinorAxis() * A * (sigma - deltaSigma);
		(*result).azimuth = atan2(cosU2 * sinLambda, dCosU1SinU2 - dSinU1CosU2 * cosLambda);
		(*result).reverseAzimuth = M_PI + atan2(cosU1 * sinLambda, -dSinU1CosU2 + dCosU1SinU2 * cosLambda);

		if((*result).reverseAzimuth < 0.0)
			(*result).reverseAzimuth = M_2PI + (*result).reverseAzimuth;

		if((*result).azimuth < 0.0)
			(*result).azimuth = M_2PI + (*result).azimuth;
        if (iterLimit>98)
            return false;
        else
            return true;
	}
예제 #7
0
double cOrbit::SpeedAtTrueAnomaly(double tA) const
{
    return std::sqrt(ReferenceBody().GravitationalParameter() * (2.0 / RadiusAtTrueAnomaly(tA) - 1.0 / SemiMajorAxis()));
}
예제 #8
0
double cOrbit::RadiusAtTrueAnomaly(double tA) const
{
    double e = Eccentricity();

    return SemiMajorAxis() * (1 - e * e) / (1 + e * std::cos(tA));
}