1

(iPhone) 我正在尝试让用户可以通过在屏幕上拖动手指来旋转对象。向左或向右拖动应围绕 Y 轴旋转,向上或向下拖动应围绕 X 轴旋转。这是我的原始代码:

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

旋转很疯狂,似乎是在随机方向。我很确定它与第二个语句依赖于第一个语句有关,但我试图用一些花哨的数学来否定它,但仍然无法正确处理。

好吧,我部分想通了,但是现在我遇到了一个新问题(如何对两个旋转求和?)。

我的解决方案:

假设您想将立方体向左旋转 90 度,然后向下旋转 90 度。您试试这个:

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

它不起作用。第二个函数的行为很奇怪,因为第一个函数交换了 X 轴和 Z 轴。所以你试试这个:

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 旋转。您必须考虑到这一点,并且您必须将这两个功能结合起来,从而导致:

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

其中 xFactor 和 yFactor 加起来就是所需的旋转向量(1,0 表示上下,0,1 表示左右,sqrt(.5),sqrt(.5) 表示对角线旋转)。

我的问题:

当用户完成一个旋转并开始一个新的旋转时,问题就出现了。您必须记住并“重新启动”先前的旋转,否则您会得到不希望的“跳转”回 0 旋转。一个新的旋转很好,我可以实现 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) );

但是在第二个新的轮换中,我现在有两个轮换可以“重新启动”。我不知道要为 amt_old、x_old、y_old 和 z_old 分配什么值。它归结为......你如何总结两个 glRotatef 旋转?

4

2 回答 2

0

xAmtyAmt以像素为单位吗?glRotatef 的输入是否以为单位(编辑:我的意思是弧度,当然)?如果是,乘以一个小数;尝试(float)(M_PI/180)每度一个像素。

这两个旋转不是可交换的。如果你很烦恼,你可以尝试计算一个组合的旋转轴(标准化向量,选择一个垂直的,然后旋转原始向量的长度),但这对于足够小的旋转可以忽略不计。


编辑:也许你想要 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 回答