【问题标题】:2-dimensional glRotatef()二维 glRotatef()
【发布时间】:2011-04-11 21:21:23
【问题描述】:

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

【问题讨论】:

    标签: iphone multidimensional-array glrotate


    【解决方案1】:

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

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


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

    【讨论】:

    • 对于我来说,1:1 的像素与度数比实际上效果很好。无论如何,我已经取得了进步。查看更新的问题。
    【解决方案2】:

    从另一个论坛的用户那里得到答案:

    // 初始化矩阵

    ...查看初始化方法

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

    ...绘制你的对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-23
      • 1970-01-01
      相关资源
      最近更新 更多