4

わかりましたので、iOS でホイールの形をした「ホイール オブ フォーチュン」タイプのエフェクトを作成しようとしています。ここで、ホイールをつかんで回転させることができます。現在、ホイールをドラッグして心ゆくまで回転させることができますが、指を離すと停止します。ホイールが自然にスピンダウンする様子をシミュレートするために、運動量または慣性を適用する必要があります。

速度の計算が用意されているので、指を持ち上げるとNSLog速度 (最小 1 から最大 100 の間) が出力されます。速度は 1 から 1800 を超える範囲の範囲です (最もハードなフリックで!)。 、今は、その速度を実際の回転に変換してオブジェクトに適用する方法と、時間の経過とともに速度を落とす方法を確立しようとしています。

私の最初の考えは次のようなものでした:与えられた速度と同じ速度でループ上で完全な円を回転させ始め、その後の回転ごとに速度を少しずつ遅くします。これにより、よりハードなスピンほど速くなり、遅くなるまでに時間がかかるという効果が得られるはずです。

私は数学者ではないので、私のアプローチは間違っているかもしれませんが、少なくとも基本的な状態でこれを機能させる方法について誰かがヒントを持っていれば、本当に感謝しています. ここに非常に役立つ答えがあります: iPhone は慣性/運動量物理学を追加して、回転制御のような「運命の輪」をアニメートしますが、それはより理論的であり、計算された速度をオブジェクトなどに正確に適用する方法に関する実用的な情報が不足しています。ここでもアニメーションのヘルプが必要になると思います。

編集: ホイールを時計回りまたは反時計回りにドラッグしているかどうかも調べる必要があります。

どうもありがとう!

4

2 に答える 2

1

詳細な例が手元にないため、大まかな答えになります。

指を離したときの速度がすでにある場合は、難しくないはずです。あなたが持っている速度は、1秒あたりのピクセル数などです。まず、その直線速度を角速度に変換する必要があります。これは、円の周囲の長さを知ることで実行2*PI*radiusでき2*PI/perimeter*velocity、角速度をラジアン/秒で取得できます。

ホイールの軸に摩擦がなければ、その速度で永遠に走り続けます。この摩擦の値を調整するだけで済みます。これは加速度であり、角加速度のピクセル/秒平方またはラジアン/秒平方で表すことができます。次に、角速度をこの角加速度で割ると、停止するまでの時間が得られます。

アニメーション時間で、方程式を使用してfinalAngle = initialAngle + angularSpeed*animationTime - angularAcceleration/2*animationTime*animationTime、アニメーションの最後でホイールが最終的な角度になるようにすることができます。次に、変換でアニメーションを実行し、得られた時間だけその角度だけ回転させ、アニメーションが緩和する必要があると言います.

これは十分にリアルに見えるはずです。そうでない場合は、上記の方程式のサンプルに基づいて、ホイールの回転プロパティのアニメーション パスを指定する必要があります。

于 2013-02-21T18:20:05.850 に答える
1

私は自分のプログラム Bit に類似したものを書きましたが、3D で回転するため、私のケースはもう少し複雑だと思います: https://itunes.apple.com/ua/app/bit/id366236469?mt=8

基本的に私がしていることは、何らかのメソッドを定期的に呼び出す NSTimer をセットアップすることです。回転行列を作成するために方向と速度を取得するだけです (私が言ったように、3D は少し厄介です :P )。速度に 1 より小さい数値を掛けて、速度を下げます。減算ではなく乗算を行う理由は、ユーザーからのスピンが 2 倍の速さである場合、オブジェクトを 2 倍長く回転させたくないためです。

ホイールがどちらの方向に回転しているかを把握するには、すべての情報がある touchesEnded:withEvent: メソッドにそれを保存するだけです。ユーザーが指を離している限り、すでに追跡が機能していると言うので、これは明らかなはずです。

私が3Dで持っているのは次のようなものです:

// MyView.h
@interface MyView : UIView {
    NSTimer *animationTimer;
}
- (void) startAnimation;
@end


// MyAppDelegate.h
@implementation MyAppDelegate

- (void) applicationDidFinishLaunching:(UIApplication *)application {
    [myView startAnimation];
}

@end

// MyView.m
GLfloat rotationMomentum = 0;
GLfloat rotationDeltaX  = 0.0f;
GLfloat rotationDeltaY  = 0.0f;

@implementation MyView
- (void)startAnimation {
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE];
}

- (void) drawView:(id)sender {
    addRotationByDegree(rotationMomentum);
    rotationMomentum /= 1.05;
    if (rotationMomentum < 0.1)
        rotationMomentum = 0.1; // never stop rotating completely
    [renderer render];
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];
    CGPoint prevloc = [aTouch previousLocationInView:self];

    rotationDeltaX = loc.x - prevloc.x;
    rotationDeltaY = loc.y - prevloc.y;

    GLfloat distance = sqrt(rotationDeltaX*rotationDeltaX+rotationDeltaY*rotationDeltaY)/4;
    rotationMomentum = distance;
    addRotationByDegree(distance);

    self->moved = TRUE;
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
}

addRotationByDegree 関数は省きましたが、この関数はグローバル変数rotationDeltaXとrotationDeltaYを使用し、既に保存されている行列に回転行列を適用し、結果を保存します。あなたの例では、おそらくもっと単純なものが必要です(X方向の動きだけがホイールを回転させると仮定しています):

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];
    CGPoint prevloc = [aTouch previousLocationInView:self];

    GLfloat distance = loc.x - prevloc.x;
    rotationMomentum = distance;
    addRotationByDegree(distance);

    self->moved = TRUE;
}

void addRotationByDegree(distance) {
    angleOfWheel += distance; // probably need to divide the number with something reasonable here to have the spin be nicer
}
于 2013-02-15T16:28:52.137 に答える