1

(iPhone)ユーザーが画面上で指をドラッグしてオブジェクトを回転できるようにしようとしています。左または右にドラッグするとY軸を中心に回転し、上または下にドラッグするとX軸を中心に回転します。これが私の元のコードです:

glRotatef( yAmt, 0, 1, 0 );
glRotatef( xAmt, 1, 0, 0 );

回転はすべてクレイジーで、ランダムな方向に進んでいるようです。私はそれが最初のステートメントに依存している2番目のステートメントと関係があるとかなり確信しています、しかし私はいくつかの派手な数学でそれを否定しようとしました、そしてそれでもそれを正しくすることができませんでした。

部分的には理解できましたが、新しい問題が発生しました(2回転を合計する方法は?)。

私の解決策:

立方体を左に90度、次に下に90度回転させたいとしましょう。これを試してみてください。

glRotatef( 90, 0, 1, 0 );
glRotatef( 90, 1, 0, 0 );

動作しません。最初の関数がX軸とZ軸を入れ替えたため、2番目の関数は奇妙な動作をします。だからあなたはこれを試してみてください:

glRotatef( 90, 0, 1, 0 );
glRotatef( 90, 0, 0, 1 );

これで目的の結果が得られましたが、最初の関数のY回転の量を180または45などに変更すると、再び失敗します。必要な回転ベクトルは、最初の関数からのY回転の量に依存します。これにより、望ましい結果が得られます。

glRotatef( yAmt, 0, 1, 0 );
glRotatef( xAmnt, cos(yAmt), 0, sin(yAmt) );

では、最初に上下に回転させてから、左から右に回転させたい場合はどうでしょうか。この最後の解決策は失敗します。これは、まず、関数の順序が間違っているためです。次に、Y軸もX回転に依存しているためです。これを考慮する必要があり、2つの機能を組み合わせる必要があります。その結果、次のようになります。

glRotatef( totalAmt, xFactor*cos(yAmt), yFactor*cos(xAmt), xFactor*sin(yAmt) + yFactor*sin(xAmt) );

xFactorとyFactorを合計すると、目的の回転ベクトルになります(上下に1,0、左右に0,1、対角回転にsqrt(.5)、sqrt(.5))。

私の問題:

問題は、ユーザーが1回転を終了し、新しい回転を開始したときに発生します。前の回転を覚えて「再実行」する必要があります。そうしないと、望ましくない「ジャンプ」が0回転に戻ります。1つの新しい回転で問題ありません。touchesEndedを実装してglRotatefのパラメーターを記憶し、次のように新しい回転に接続できます。

glRotatef( amt_old, x_old, y_old, z_old );
glRotatef( totalAmt, xFactor*cos(yAmt), yFactor*cos(xAmt), xFactor*sin(yAmt) + yFactor*sin(xAmt) );

しかし、2回目の新しいローテーションでは、「再活性化」するための2つのローテーションがあります。amt_old、x_old、y_old、z_oldに割り当てる値がわかりません。つまり、2つのglRotatef回転をどのように合計しますか?

4

2 に答える 2

0

xAmtピクセル単位ですかyAmt?glRotatefへの入力は単位ですか(編集:もちろん、ラジアンを意味します)?もしそうなら、小さな数を掛けます。(float)(M_PI/180)1度あたり1ピクセルを試してください。

2つの回転は可換ではありません。十分に気になる場合は、結合された回転軸を計算してみることができます(ベクトルを正規化し、垂直なものを選択し、元のベクトルの長さだけ回転します)が、回転が十分に小さい場合は無視できます。


編集:おそらく、glGetMatrix()とglLoadMatrix()が必要です。

于 2011-04-12T03:12:33.110 に答える
0

別のフォーラムのユーザーから回答を得ました:

// マトリックスを初期化します

... ビューの初期化メソッド

theCurrentMatrix = CATransform3DIdentity;

...

// ユーザーがスクリーンにタッチしたときの回転を計算します:

- (void) rotateX:(float)inX Y:(float)inY
{
     GLfloat lAngle=sqrt(inX*inX+inY*inY);

 if (lAngle != 0.0f)
 {
      static const float _degToRad = M_PI / 180.0;
            // we compute a rotation matrix (in radians)
      CATransform3D lRotation = CATransform3DMakeRotation(lAngle * _degToRad, inX, inY, 0.0f);

            // apply the rotation to the current matrix (cumulative effect)
            // order is important
      theCurrentMatrix = CATransform3DConcat(theCurrentMatrix, lRotation);
 }

}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
     // Get touch
     UITouch *touch = [[touches allObjects] objectAtIndex:0];

     if ([touches count] == 1)
     {
          UITouch *touch = [[touches allObjects] objectAtIndex:0];
          CGPoint location = [touch locationInView:touch.view];
      CGPoint previousLocation = [touch previousLocationInView:touch.view];

      CGFloat lDeltaX = (location.x - previousLocation.x)*1.0;
      CGFloat lDeltaY = (location.y - previousLocation.y)*1.0;

      // rotate the current matrix
      [self rotateX:lDeltaYY:lDeltaX];
 }

}

// 回転を適用中 ...

glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();


 glTranslatef(0.0f,0.0f,-100.0f);   // move a little to see the object


 glMultMatrixf(theCurrenMatrixPtr]);

... オブジェクトを描画します

于 2011-06-14T02:54:26.283 に答える