【问题标题】:Rotating an OpenGL ES Object with GLKit使用 GLKit 旋转 OpenGL ES 对象
【发布时间】:2012-01-23 08:38:15
【问题描述】:

我正在尝试使用触摸在 iOS 中旋转 OpenGL 对象,但遇到了一些问题。我在这里抓住了用户的触摸:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
    UITouch *touch = [touches anyObject];
    startPoint = [touch locationInView:self.view];
    }

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
   {
   UITouch *touch = [touches anyObject];
   CGPoint point = [touch locationInView:self.view];
   dx = point.y - startPoint.y;
   dy = point.x - startPoint.x;
   startPoint = point;
   }

我在我的更新函数中使用它来执行轮换。现在,当我从左到右触摸时,我只是尝试从左到右旋转,然后在上下触摸时从前到后旋转。我得到了一个奇怪的组合轮换。代码如下:

- (void)update
   {    
   float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
   GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);

   self.effect.transform.projectionMatrix = projectionMatrix;

   GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -3.5f);
   modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, -1, startPoint.x, startPoint.y, 0.0f);
   dx = dy =0;
   self.effect.transform.modelviewMatrix = modelViewMatrix;
   }

【问题讨论】:

  • 不确定如何在 GLK 中执行,但您是否在旋转之前将其转换为原点(然后再返回)?
  • 不,我不认为我正在这样做。物体并没有从屏幕上移开,它在旋转,只是不是我想要的。我应该这样做吗?
  • 在 OpenGL 中,您首先将对象平移(=滑动)到原点 (0,0,0),然后旋转它,然后将其平移回它的假定位置。 OpenGL 总是围绕原点旋转,如果你不将它滑到那里,你的对象会“绕”原点“旋转”,但不会像预期的那样围绕自身旋转。
  • 注意:如果你只想绕 Y 轴旋转,将其转换为 Y = 0 等就足够了。希望我能帮助你。
  • 我实际上已经将它翻译成原点。 GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -3.5f);

标签: ios opengl-es touch rotation glkit


【解决方案1】:

因为你告诉它在 x 和 y 中旋转 :)

试试这个:

modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, startPoint.x, 1.0f, 0.0f, 0.0f);

这将围绕 x 轴旋转 startPoint.x 弧度。

您可以通过更改最后 3 个参数来围绕您想要的任何轴旋转(即 0,1,0 将围绕 y 轴旋转,1,1,0 将围绕 x 和 y 之间的 45° 轴旋转。 )

NB 感谢@Marcelo Cantos 的澄清:)

【讨论】:

  • 感谢您的回答。我理解你的推理,这是有道理的。我试了一下,但现在它根本不动。
  • 我想通了。你在正确的轨道上。我不确定为什么我所拥有的仍然不起作用,但我发现了一些有效的东西。我没有使用 GLKMatrix4Rotate() 同时进行两个移动,而是使用 GLKMatrix4RotateX() 和 GLKMatrix4RotateY()。
  • 抱歉,我误读了方法签名,弄乱了我的坐标轴/弧度 - 抱歉!查看我的编辑以获得更好的答案!
  • @deanWombourne:您的解释具有误导性。它给人的印象是,例如,将最后一个参数设置为 1.0f 将围绕 x 轴 z 轴旋转 startPoint.x(无论这可能需要什么)。旋转总是围绕由任意向量定义的单个轴表示。在这种情况下,旋转轴恰好与 x 轴对齐。如果您确实将最后一个参数更改为 1.0f,您将获得围绕 x 轴和 z 轴之间 45° 的向量的单次旋转(不是两次旋转)。
  • @Marcelo Cantos - 哦,我没想到会这样读;我已经编辑了我的答案:) 谢谢。
【解决方案2】:

根据 deanWombourne 的说法,您错误地使用了 GLKMatrix4Rotate。执行时:

GLKMatrix4Rotate(modelViewMatrix, -1, startPoint.x, startPoint.y, 0.0f);

您围绕轴旋转 -1 弧度(startPoint.x、startPoint.y、0.0f)。这听起来更像是您想围绕 (1, 0, 0) 旋转 startPoint.x 弧度,并围绕 (0, 1, 0) 旋转 startPoint.y 弧度。所以,例如:

modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, startPoint.x, 1.0f, 0.0f 0.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, startPoint.y, 0.0f, 1.0f 0.0f);

或者您可能想要划分 startPoint.x 和 startPoint.y,因为这会对触摸产生超强响应。

它还会有一些万向节锁定问题——本质上是因为如果你先绕 x 旋转,那么 y 轴不一定在你认为的位置,如果你先绕 y 旋转,那么 x 轴不一定你认为它在哪里。这是你担心的事情吗?

【讨论】:

  • 谢谢。我现在看得更清楚了。我注意到 startPoint 非常敏感的问题。我把它分解了。我希望模型像你的手指一样移动。如果您以某个角度移动,我希望它可以上下旋转。我使用 RotateX 和 RotateY 分离出来的代码似乎就是这样操作的。不过,我不知道如何让它停止咬你的手指。
猜你喜欢
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 2012-08-25
相关资源
最近更新 更多