【问题标题】:valid way to calculate angle between 2 CLLocations?计算 2 个 CLLocations 之间角度的有效方法?
【发布时间】:2011-10-18 23:29:52
【问题描述】:

这是计算从一个 CLLocation 到另一个的角度(以弧度为单位)的有效方法吗?

-(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;}

请指教!

任何帮助将不胜感激。

【问题讨论】:

标签: coordinates core-location augmented-reality angle


【解决方案1】:

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
        }
    }
}

【讨论】:

  • 工作得很好,因为我直接在类中使用了扩展函数,因为在扩展中我收到了这个错误:“Equatable”的实现不能在不同文件的扩展中自动合成到类型
  • 您的代码运行良好。请在您的代码中添加一些有助于理解的解释。谢谢
【解决方案2】:

我使用了这个question and answer 的变体,效果很好:

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;
    }
}

【讨论】:

  • 我也有类似的问题。我正在根据 GPS 读数跟踪用户的位置。 GPS读数给了我一个“航向”值,它决定了正北方向的度数。当我计算两个坐标之间的角度差时,如果用户从 0 度移动到 359 度,事情就会变得很糟糕。实时,它可能是 1 度的变化,但我的代码给出了 359 度的变化。有什么想法吗?
【解决方案3】:

我发现进行此计算的最佳方法是使用球面余弦定律。有一个可用的 C 函数 here on github 称为 headingInDegrees。它需要两个纬度/经度对并返回标题:

/*------------------------------------------------------------------------- 
* 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 包含纬度和经度,因此很容易将这两个字段传递给此函数并返回航向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多