4

加速度計を使用して、円内で画像を移動しようとしています。画像が円の端に当たると、円の反対側に移動するだけであるという問題があります。私のコードは以下の通りです:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
//NSLog(@"x : %g", acceleration.x);
//NSLog(@"y : %g", acceleration.y);
//NSLog(@"z : %g", acceleration.z);

delta.x = acceleration.x * 10;
delta.y = acceleration.y * 10;

joypadCap.center = CGPointMake(joypadCap.center.x + delta.x, joypadCap.center.y - delta.y);

distance = sqrtf(((joypadCap.center.x - 160) * (joypadCap.center.x - 160)) +
                 ((joypadCap.center.y -206) * (joypadCap.center.y - 206)));
//NSLog(@"Distance : %f", distance);


touchAngle = atan2(joypadCap.center.y, joypadCap.center.x);
NSLog(@"Angle : %f", touchAngle);


if (distance > 50) {
    joypadCap.center = CGPointMake(160 - cosf(touchAngle) * 50, 206 - sinf(touchAngle) * 50);
}
4

1 に答える 1

4

CMDeviceMotion を使用して円形の水準器を実装しようとすると、同じ問題が発生しました。に渡される座標に問題があることがわかりましたatan2(y,x)。この関数には、(0,0) がビューの中心にあるデカルト座標が必要です。ただし、画面座標は左上隅に (0,0) があります。2 つの座標系の間でポイントを変換するメソッドを作成しましたが、今ではうまく機能しています。

サンプル プロジェクトを github に上げました、最も重要な部分は次のとおりです。

float distance = sqrtf(((point.x - halfOfWidth) * (point.x - halfOfWidth)) +
                       ((point.y - halfOfWidth) * (point.y - halfOfWidth)));

if (distance > maxDistance)
{
    // Convert point from screen coordinate system to cartesian coordinate system,
    // with (0,0) located in the centre of the view
    CGPoint pointInCartesianCoordSystem = [self convertScreenPointToCartesianCoordSystem:point
                                                                                 inFrame:self.view.frame];

    // Calculate angle of point in radians from centre of the view
    CGFloat angle = atan2(pointInCartesianCoordSystem.y, pointInCartesianCoordSystem.x);

    // Get new point on the edge of the circle
    point = CGPointMake(cos(angle) * maxDistance, sinf(angle) * maxDistance);

    // Convert back to screen coordinate system
    point = [self convertCartesianPointToScreenCoordSystem:point inFrame:self.view.frame];
}

と:

- (CGPoint)convertScreenPointToCartesianCoordSystem:(CGPoint)point
                                            inFrame:(CGRect)frame
{
    float x = point.x - (frame.size.width / 2.0f);
    float y = (point.y - (frame.size.height / 2.0f)) * -1.0f;

    return CGPointMake(x, y);
}

- (CGPoint)convertCartesianPointToScreenCoordSystem:(CGPoint)point
                                            inFrame:(CGRect)frame
{
    float x = point.x + (frame.size.width / 2.0f);
    float y = (point.y * -1.0f) + (frame.size.height / 2.0f);

    return CGPointMake(x, y);
}
于 2013-05-03T09:26:28.803 に答える