Пример #1
0
/// New functions
void DistanceBearingMercator(double lat0, double lon0, double lat1, double lon1, double *dist, double *brg)
{
	//    Calculate bearing by conversion to SM (Mercator) coordinates, then simple trigonometry

	double lon0x = lon0;
	double lon1x = lon1;

	//    Make lon points the same phase
	if ((lon0x * lon1x) < 0.)
	{
		lon0x < 0.0 ? lon0x += 360.0 : lon1x += 360.0;
		//    Choose the shortest distance
		if (fabs(lon0x - lon1x) > 180.)
		{
			lon0x > lon1x ? lon0x -= 360.0 : lon1x -= 360.0;
		}

		//    Make always positive
		lon1x += 360.;
		lon0x += 360.;
	}

	//    Classic formula, which fails for due east/west courses....
	if (dist)
	{
		//    In the case of exactly east or west courses
		//    we must make an adjustment if we want true Mercator distances

		//    This idea comes from Thomas(Cagney)
		//    We simply require the dlat to be (slightly) non-zero, and carry on.
		//    MAS022210 for HamishB from 1e-4 && .001 to 1e-9 for better precision
		//    on small latitude diffs
		const double mlat0 = fabs(lat1 - lat0) < 1e-9 ? lat0 + 1e-9 : lat0;

		double east, north;
		toSM_ECC(lat1, lon1x, mlat0, lon0x, &east, &north);
		const double C = atan2(east, north);
		if (cos(C))
		{
			const double dlat = (lat1 - mlat0) * 60.;              // in minutes
			*dist = (dlat / cos(C));
		}
		else
		{
			*dist = DistGreatCircle(lat0, lon0, lat1, lon1);
		}
	}

	//    Calculate the bearing using the un-adjusted original latitudes and Mercator Sailing
	if (brg)
	{
		double east, north;
		toSM_ECC(lat1, lon1x, lat0, lon0x, &east, &north);

		const double C = atan2(east, north);
		const double brgt = 180. + (C * 180. / PI);
		if (brgt < 0)
			*brg = brgt + 360.;
		else if (brgt >= 360.)
			*brg = brgt - 360.;
		else
			*brg = brgt;
	}
}
Пример #2
0
void DistanceBearingMercator(double lat0, double lon0, double lat1, double lon1, double *brg, double *dist)
{
    double east, north, brgt, C;
    double lon0x, lon1x, dlat;
    double mlat0;

    //    Calculate bearing by conversion to SM (Mercator) coordinates, then simple trigonometry

    lon0x = lon0;
    lon1x = lon1;

    //    Make lon points the same phase
    if((lon0x * lon1x) < 0.)
    {
        if(lon0x < 0.)
            lon0x += 360.;
        else
            lon1x += 360.;

        //    Choose the shortest distance
        if(fabs(lon0x - lon1x) > 180.)
        {
            if(lon0x > lon1x)
                lon0x -= 360.;
            else
                lon1x -= 360.;
        }

        //    Make always positive
        lon1x += 360.;
        lon0x += 360.;
    }

    //    In the case of exactly east or west courses
    //    we must make an adjustment if we want true Mercator distances

    //    This idea comes from Thomas(Cagney)
    //    We simply require the dlat to be (slightly) non-zero, and carry on.
    //    MAS022210 for HamishB from 1e-4 && .001 to 1e-9 for better precision
    //    on small latitude diffs
    mlat0 = lat0;
    if(fabs(lat1 - lat0) < 1e-9)
        mlat0 += 1e-9;

    toSM_ECC(lat1, lon1x, mlat0, lon0x, &east, &north);

    C = atan2(east, north);
    dlat = (lat1 - mlat0) * 60.;              // in minutes

    //    Classic formula, which fails for due east/west courses....

    if(dist)
    {
        if(cos(C))
            *dist = (dlat /cos(C));
        else
            *dist = DistGreatCircle(lat0, lon0, lat1, lon1);

    }

    //    Calculate the bearing using the un-adjusted original latitudes and Mercator Sailing
    if(brg)
    {
        toSM_ECC(lat1, lon1x, lat0, lon0x, &east, &north);

        C = atan2(east, north);
        brgt = 180. + (C * 180. / PI);
        if (brgt < 0)
            brgt += 360.;
        if (brgt > 360.)
            brgt -= 360;

        *brg = brgt;
    }


    //    Alternative formulary
    //  From Roy Williams, "Geometry of Navigation", we have p = Dlo (Dlat/DMP) where p is the departure.
    // Then distance is then:D = sqrt(Dlat^2 + p^2)

    /*
              double dlo =  (lon1x - lon0x) * 60.;
              double departure = dlo * dlat / ((north/1852.));

              if(dist)
                 *dist = sqrt((dlat*dlat) + (departure * departure));
    */



}