правильный способ рассчитать угол между 2 CLLocations? - PullRequest
3 голосов
/ 03 августа 2011

Является ли это допустимым способом вычисления угла (в радианах) от одного расположения CLL к другому?

-(float)angleFromLocation:(CLLocationCoordinate2D)start toLocation:(CLLocationCoordinate2D)end {
float deltaX = start.latitude - end.latitude;
float deltaY = start.longitude - end.longitude;
float ang = atan2(deltaY, deltaX);

return ang;}

Пожалуйста, сообщите!

Любая помощь будет высоко ценится.

Ответы [ 3 ]

2 голосов
/ 17 октября 2015

Я использовал вариант этого вопроса и ответа , и он хорошо работает:

double DegreesToRadians(double degrees) {return degrees * M_PI / 180.0;};
double RadiansToDegrees(double radians) {return radians * 180.0/M_PI;};

- (double)bearingFromLocation:(CLLocation *)fromLocation toLocation:(CLLocation *)toLocation
{

    double lat1 = DegreesToRadians(fromLocation.coordinate.latitude);
    double lon1 = DegreesToRadians(fromLocation.coordinate.longitude);

    double lat2 = DegreesToRadians(toLocation.coordinate.latitude);
    double lon2 = DegreesToRadians(toLocation.coordinate.longitude);

    double dLon = lon2 - lon1;

    double y = sin(dLon) * cos(lat2);
    double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
    double radiansBearing = atan2(y, x);

    double degreesBearing = RadiansToDegrees(radiansBearing);

    if (degreesBearing >= 0) {
        return degreesBearing;
    } else {
        return degreesBearing + 360.0;
    }
}
2 голосов
/ 03 ноября 2017

Swift 4 версия:

extension FloatingPoint {

    var degreesToRadians: Self { return self * .pi / 180 }
    var radiansToDegrees: Self { return self * 180 / .pi }
}

extension CLLocationCoordinate2D: Equatable {

    func heading(to: CLLocationCoordinate2D) -> Double {
        let lat1 = self.latitude.degreesToRadians
        let lon1 = self.longitude.degreesToRadians

        let lat2 = to.latitude.degreesToRadians
        let lon2 = to.longitude.degreesToRadians

        let dLon = lon2 - lon1
        let y = sin(dLon) * cos(lat2)
        let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)

        let headingDegrees = atan2(y, x).radiansToDegrees
        if headingDegrees >= 0 {
            return headingDegrees
        } else {
            return headingDegrees + 360
        }
    }
}
0 голосов
/ 08 сентября 2011

Лучший метод, который я нашел для этого вычисления, заключался в использовании сферического закона косинусов.Существует функция C, чтобы сделать это доступной здесь на github , называемая headingInDegrees.Он принимает две пары lat / long и возвращает заголовок:

/*------------------------------------------------------------------------- 
* Given two lat/lon points on earth, calculates the heading 
* from lat1/lon1 to lat2/lon2.   
*  
* lat/lon params in degrees 
* result in degrees 
*-------------------------------------------------------------------------*/
double headingInDegrees(double lat1, double lon1, double lat2, double lon2);

Поскольку CLLocationCoordinate2d содержит широту и долготу, эти два поля легко передать в эту функцию и вернуть заголовок.

...