计算位置的度数

时间:2012-05-17 20:07:06

标签: ios math gps core-location direction

我正在构建一个应该向某个位置显示箭头的应用程序。例如,如果我在位置X并且目标设置为位置Y,它应该显示一个直接指向该位置的箭头。

在搜索和搜索之后,我发现有一些计算这个的奇特公式,但我似乎一遍又一遍地弄错了。

这是我的问题。虽然它似乎找到了正确的初始位置,但一旦我转动我的设备,“箭头”就会朝相反的方向或它应该的方向转动。因此,如果我顺时针转动设备,箭头也顺时针转动......反之亦然。

这是我的一些代码:

@implementation CompassViewController

BOOL firstPositionFound = NO;
float lastPosition = 0;
float currentHeading = 0;

[...]

#pragma mark - 
#pragma mark Core Location Methods

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    if (newHeading.headingAccuracy > 0) {
        CLLocationDirection theHeading = newHeading.magneticHeading;

        currentHeading = theHeading;

        [self fixPointer:theHeading];
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
    self.currentLocation = newLocation;

    [self fixPointer:currentHeading];
}

- (void)fixPointer:(float)heading
{
    float degree = [self calculateDegree:self.currentLocation];

    degree = heading - degree;

    NSLog(@"heading: %f, Degree: %f", heading, degree);

    NSLog(@"Degree 2: %f", degree);

    self.arrowView.transform = CGAffineTransformMakeRotation(degreesToRadians(degree));
}

#pragma mark -
#pragma mark Delegate methods

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark -
#pragma mark Other methods

- (float)calculateDegree:(CLLocation *)newLocation
{
    CLLocationCoordinate2D from = newLocation.coordinate;
    CLLocationCoordinate2D to;
    to.latitude = APP_DESTINATION_LAT;
    to.longitude = APP_DESTINATION_LON;

    float res = atan2(sin((to.longitude*M_PI/180)-(from.longitude*M_PI/180))*cos(to.latitude*M_PI/180),
                      cos(from.latitude*M_PI/180)*sin(to.latitude*M_PI/180)-sin(from.latitude*M_PI/180)*cos(to.latitude*M_PI/180)*cos((to.longitude*M_PI/180)-(from.longitude*M_PI/180)));

    res = res/M_PI*180;

    if (res < 0)
        res = 360.0f + res;

    return res;
}

#pragma mark -

我只是输了,有人可以指出我哪里出错了吗?我想这是一个简单的事情,我现在不敢看。

2 个答案:

答案 0 :(得分:2)

看看Stack Overflow问题中的答案:

CLLocation Category for Calculating Bearing w/ Haversine function

具体来说,这部分:

如果您获得负面方位,请在radiansBearing中将最终结果加2 * M_PI(如果转换为度数后再加上360)。 atan2返回范围-M_PI到M_PI(-180到180度)的结果,因此您可能希望将其转换为罗盘方位,使用类似下面的代码

if(radiansBearing < 0.0)
    radiansBearing += 2*M_PI;**

此外,除非您始终以纵向方式握住设备,否则需要针对设备方向和角度调整标题信息。慢慢将设备转到横向模式,您将看到标题值改变90°。

答案 1 :(得分:0)

检查一下 Wikipedia - On rotation matrix

从我理解的代码中你可以看出sin元素和给定(x,y)坐标的cos元素之间的角度。 [基本上由(tan(x,0)/(0,y))]

给出

让我们称之为角度theta。

你应该做的是取这个坐标并乘以

CC wikipedia

让我们调用新坐标(x',y')

x'

y'

希望这有帮助。