二维glRotatef()

时间:2011-04-11 21:21:24

标签: iphone multidimensional-array glrotate

(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旋转?

2 个答案:

答案 0 :(得分:0)

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

两次轮换不是可交换的。如果你有足够的麻烦,你可以尝试计算一个组合的旋转轴(标准化矢量,选择一个垂直的旋转,并按长度旋转 原始矢量),但这对于足够小的旋转来说可以忽略不计。


编辑:也许你想要glGetMatrix()和glLoadMatrix()。

答案 1 :(得分:0)

在另一个论坛上得到了用户的答案:

//初始化矩阵

...查看init方法

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]);

...画出你的物品