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 -

私は迷子になっています。どこが間違っていたのか誰かに指摘してもらえますか?私が現在目がくらんでいるのは、簡単なことだと思います。

4

2 に答える 2

2

このStackOverflowの質問の答えを見てください:

Haversine関数を使用してベアリングを計算するためのCLLocationカテゴリ

具体的には、この部分:

負の方位を取得している場合は、radiansBearingの最終結果に2 * M_PIを追加します(度に変換した後に行う場合は360)。atan2は、-M_PIからM_PI(-180から180度)の範囲の結果を返すため、次のコードのようなものを使用して、コンパス方位に変換することをお勧めします。

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

また、デバイスを常に縦向きに保持している場合を除き、見出し情報はデバイスの向きと角度に合わせて調整する必要があります。デバイスをゆっくりと横向きモードにすると、方位値が90°変化します。

于 2012-05-18T00:40:16.880 に答える
0

ウィキペディアをチェックして ください-回転行列について

コードから、与えられた(x、y)座標のsin要素とcos要素の間に角度があることがわかります。[基本的に(tan(x、0)/(0、y))で与えられる]

この角度シータと呼びましょう。

あなたがすべきことは、この座標を取り、それを乗算することです

CCウィキペディア

新しい座標(x'、y')を呼び出しましょう

バツ'

y '

お役に立てれば。

于 2012-05-17T22:20:29.703 に答える