Поверните изображение, чтобы направить его на хорошо известную точку, используя направление по компасу.

В качестве доказательства концепции я хочу создать приложение, которое извлекает текущие координаты, вычисляет направление к другой точке и, используя компас, поворачивает изображение стрелки, чтобы направить ее в эту точку в пространстве.

Я знаю, как получить текущую координату и повернуть изображение через CGAffineTransformMakeRotation, но я не нашел формулы для вычисления правильного угла.

Любые подсказки?


person Giordano Scalzo    schedule 11.10.2010    source источник


Ответы (2)


Сначала нужно рассчитать подшипник. Эта страница дает опрятную формулу для этого:

http://www.movable-type.co.uk/scripts/latlong.html

Затем вы можете выполнить простую арифметику, чтобы найти разницу между этим направлением и направлением, на которое указывает iPhone. Поверните изображение на эту разницу.

person Josh Hinman    schedule 12.10.2010
comment
хорошо, благодаря этой замечательной странице я вычисляю правильный пеленг; к сожалению, я пробовал разные формулы, чтобы найти разницу, но не нашел подходящей: не могли бы вы указать мне правильную операцию? - person Giordano Scalzo; 13.10.2010

Подшипник это:

double bearingUsingStartCoordinate(CLLocation *start, CLLocation *end)
{
    double tc1;
    tc1 = 0.0;

    //dlat = lat2 - lat1
    //CLLocationDegrees dlat = end.coordinate.latitude - start.coordinate.latitude; 

    //dlon = lon2 - lon1
    CLLocationDegrees dlon = end.coordinate.longitude - start.coordinate.longitude;

    //y = sin(lon2-lon1)*cos(lat2)
    double y = sin(d2r(dlon)) * cos(d2r(end.coordinate.latitude));

    //x = cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1)
    double x = cos(d2r(start.coordinate.latitude))*sin(d2r(end.coordinate.latitude)) - sin(d2r(start.coordinate.latitude))*cos(d2r(end.coordinate.latitude))*cos(d2r(dlon)); 

    if (y > 0)
    {
        if (x > 0)
            tc1 = r2d(atan(y/x));

        if (x < 0)
            tc1 = 180 - r2d(atan(-y/x));

        if (x == 0)
            tc1 = 90;

    } else if (y < 0)
    {
        if (x > 0)
            tc1 = r2d(-atan(-y/x));

        if (x < 0)
            tc1 = r2d(atan(y/x)) - 180;

        if (x == 0)
            tc1 = 270;

    } else if (y == 0)
    {
        if (x > 0)
            tc1 = 0;

        if (x < 0)
            tc1 = 180;

        if (x == 0)
            tc1 = nan(0);
    }
    if (tc1 < 0)
        tc1 +=360.0;
        return tc1;
}

И для тех, кто ищет расстояние между двумя точками:

double haversine_km(double lat1, double long1, double lat2, double long2)
{
    double dlong = d2r(long2 - long1);
    double dlat = d2r(lat2 - lat1);
    double a = pow(sin(dlat/2.0), 2) + cos(d2r(lat1)) * cos(d2r(lat2)) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 6367 * c;

    return d;
}

double haversine_mi(double lat1, double long1, double lat2, double long2)
{
    double dlong = d2r(long2 - long1);
    double dlat = d2r(lat2 - lat1);
    double a = pow(sin(dlat/2.0), 2) + cos(d2r(lat1)) * cos(d2r(lat2)) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 3956 * c; 

    return d;
}
person Peter Greis    schedule 10.01.2011