2012-05-17 150 views
1

我正在构建应该向某个位置显示箭头的应用程序。例如,如果我在位置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

在这个堆栈溢出问题,看看答案:

CLLocation Category for Calculating Bearing w/ Haversine function

具体而言,本部分:

如果您收到了消极的影响,加上2 * M_PI最终结果以radiansBearing(如果在转换为度数后执行,则为360)。 ATAN2返回结果的范围-M_PI到M_PI(-180〜180度),因此您可能需要将其转换为罗盘方位,使用类似下面的代码

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

另外,标题信息需要除非您始终将您的设备放在肖像中,否则请调整设备方向和角度。将设备慢慢转到横向模式,您将看到您的标题值改变了90°。

+0

谢谢!你的回答确实对我有帮助。我更新了我所提供的代码,这种方式更好。不过,我还有一个问题,现在:它似乎为我的经度/纬度向目的地正确度...但它预计手机有0标题(指向北方)。如果我计算从轴承中减去标题的半径,它仍然不准确。有什么建议吗? –

+0

@珍妮-B你对我有什么建议吗? –

+1

@Paul Peelen没有看到您的代码,我不知道如何回答您,但是,简单的答案是确保您使用正确的单位并调整设备方向。因此,请确保您正在从度数减去度数,而不是从弧度减去度数,并确保您已从磁力仪获得的值已根据设备方向进行调整。 – Jenn

0

检查了这一点 Wikipedia - On rotation matrix

从我从你的罪元素和给定(X,Y)的COS单元坐标之间的夹角代码理解。 [基本上由下式给出(TAN(X,0)/(0,y)的)]

让调用这个角度theta。

你应该做的是采取这种协调和

CC wikipedia

乘以它让我们称之为新坐标(X 'Y')

x'

y'

希望这有助于。