How to get angle between two POI?

半腔热情 提交于 2019-12-29 08:02:34

问题


How do I calculate the angle in degrees between the coordinates of two POIs (points of interest) on an iPhone map application?


回答1:


I'm guessing you try to calculate the degrees between the coordinates of two points of interest (POI).

Calculating the arc of a great circle:

+(float) greatCircleFrom:(CLLocation*)first 
                      to:(CLLocation*)second {

    int radius = 6371; // 6371km is the radius of the earth
    float dLat = second.coordinate.latitude-first.coordinate.latitude;
    float dLon = second.coordinate.longitude-first.coordinate.longitude;
    float a = pow(sin(dLat/2),2) + cos(first.coordinate.latitude)*cos(second.coordinate.latitude) * pow(sin(dLon/2),2);
    float c = 2 * atan2(sqrt(a),sqrt(1-a));
    float d = radius * c;

    return d;
}

Another option is to pretend you are on cartesian coordinates (faster but not without error on long distances):

+(float)angleFromCoordinate:(CLLocationCoordinate2D)first 
               toCoordinate:(CLLocationCoordinate2D)second {

    float deltaLongitude = second.longitude - first.longitude;
    float deltaLatitude = second.latitude - first.latitude;
    float angle = (M_PI * .5f) - atan(deltaLatitude / deltaLongitude);

    if (deltaLongitude > 0)      return angle;
    else if (deltaLongitude < 0) return angle + M_PI;
    else if (deltaLatitude < 0)  return M_PI;

    return 0.0f;
}

If you want the result in degrees instead radians, you have to apply the following conversion:

#define RADIANS_TO_DEGREES(radians) ((radians) * 180.0 / M_PI)



回答2:


You are calculating the 'Bearing' from one point to another here. There's a whole bunch of formula for that, and lots of other geographic quantities like distance and cross-track error, on this web page:

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

the formulae are in several formats so you can easily convert to whatever language you need for your iPhone. There's also javascript calculators so you can test your code gets the same answers as theirs.




回答3:


If the other solutions dont work for you try this:

- (int)getInitialBearingFrom:(CLLocation *)first
                        to:(CLLocation *)second
{
    float lat1 = [self degreesToRad:first.coordinate.latitude];
    float lat2 = [self degreesToRad:second.coordinate.latitude];
    float lon1 = [self degreesToRad:first.coordinate.longitude];
    float lon2 = [self degreesToRad:second.coordinate.longitude];
    float dLon = lon2 - lon1;
    float y = sin (dLon) * cos (lat2);
    float x1 = cos (lat1) * sin (lat2);
    float x2 = sin (lat1) * cos (lat2) * cos (dLon);
    float x = x1 - x2;
    float bearingRadRaw = atan2f (y, x);
    float bearingDegRaw = bearingRadRaw * 180 / M_PI;
    int bearing = ((int) bearingDegRaw + 360) % 360; // +- 180 deg to 360 deg

    return bearing;
}

For final bearing, simply take the initial bearing from the end point to the start point and reverse it (using θ = (θ+180) % 360).

You need these 2 helpers:

-(float)radToDegrees:(float)radians
{
    return radians * 180 / M_PI;
}
-(float)degreesToRad:(float)degrees
{
    return degrees * M_PI /180;
}


来源:https://stackoverflow.com/questions/6140045/how-to-get-angle-between-two-poi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!