0

こんにちは私はテーブルの丸いトップのようなイメージを持っています。ユーザーが左から右にスワイプするときは時計回りに、右から左にスワイプするときは反時計回りに動かしたいと思います。

ラウンドテーブルトップをリアルタイムで動かすようなものです。アプリでこれを行うにはどうすればよいですか?

次のコードをローテーションに使用しています。そのTrackBallの例から。私が抱えている問題は、画像が回転するたびにその位置が変わることです。

- (CATransform3D)rotationTransformForLocation:(CGPoint)location 
{  
    CGFloat trackBallCurrentPoint[3] = {location.x - trackBallCenter.x, location.y - trackBallCenter.y, 0.0f};

    if(fabs(trackBallCurrentPoint[0] - trackBallStartPoint[0]) < kTol && fabs(trackBallCurrentPoint[1] - trackBallStartPoint[1]) < kTol) 
    {
        return CATransform3DIdentity;
    }

    CGFloat dist = trackBallCurrentPoint[0] * trackBallCurrentPoint[0] + trackBallCurrentPoint[1] * trackBallCurrentPoint[1];
    if(dist > trackBallRadius * trackBallRadius) 
    {
        // outside the center of the sphere so make it zero
        trackBallCurrentPoint[2] = 0.0f;
    } 
    else 
    {
        trackBallCurrentPoint[2] = sqrt(trackBallRadius * trackBallRadius - dist);
    }

    // cross product yields the rotation vector
    CGFloat rotationVector[3];
    rotationVector[0] =  trackBallStartPoint[1] * trackBallCurrentPoint[2] - trackBallStartPoint[2] * trackBallCurrentPoint[1];
    rotationVector[1] = -trackBallStartPoint[0] * trackBallCurrentPoint[2] + trackBallStartPoint[2] * trackBallCurrentPoint[0];
    rotationVector[2] =  trackBallStartPoint[0] * trackBallCurrentPoint[1] - trackBallStartPoint[1] * trackBallCurrentPoint[0];

    // calc the angle between the current point vector and the starting point vector
    // use arctan so we get all eight quadrants instead of just the positive ones

    // cos(a) = (start . current) / (||start|| ||current||)
    // sin(a) = (||start X current||) / (||start|| ||current||)
    // a = atan2(sin(a), cos(a))
    CGFloat startLength = sqrt(trackBallStartPoint[0] * trackBallStartPoint[0] + trackBallStartPoint[1] * trackBallStartPoint[1] + trackBallStartPoint[2] * trackBallStartPoint[2]);
    CGFloat currentLength = sqrt(trackBallCurrentPoint[0] * trackBallCurrentPoint[0] + trackBallCurrentPoint[1] * trackBallCurrentPoint[1] + trackBallCurrentPoint[2] * trackBallCurrentPoint[2]);
    CGFloat startDotCurrent = trackBallStartPoint[0] * trackBallCurrentPoint[0] + trackBallStartPoint[1] * trackBallCurrentPoint[1] + trackBallStartPoint[2] * trackBallCurrentPoint[2]; // (start . current)

    // start X current we have already calcualted in the rotation vector
    CGFloat rotationLength = sqrt(rotationVector[0] * rotationVector[0] + rotationVector[1] * rotationVector[1] + rotationVector[2] * rotationVector[2]);

    CGFloat angle = atan2(rotationLength / (startLength * currentLength), startDotCurrent / (startLength * currentLength));

    // normalize the rotation vector
    rotationVector[0] = rotationVector[0] / rotationLength;
    rotationVector[1] = rotationVector[1] / rotationLength;
    rotationVector[2] = rotationVector[2] / rotationLength;

    CATransform3D rotationTransform = CATransform3DMakeRotation(angle, rotationVector[0], rotationVector[1], rotationVector[2]);
    return CATransform3DConcat(baseTransform, rotationTransform);
}

前もって感謝します。

4

1 に答える 1

2

私が提起した質問を見てください...あなたは同じことをしようとしているかもしれません(質問はそれをカバーしていないと思いますが、回転が機能した後、ユーザーがどちらかでディスクを回転できるようにパンジェスチャを実装しました方向)

透視図でフラットオブジェクトをその中心の周りで回転させる方法は?

于 2012-06-29T16:48:24.407 に答える