Android 使用openGL中的触摸屏控制3D对象的旋转

Android 使用openGL中的触摸屏控制3D对象的旋转,android,opengl-es,3d,rotation,touch-event,Android,Opengl Es,3d,Rotation,Touch Event,我是一名四年级计算机工程专业的学生,有一些安卓开发经验 我正在开发一个应用程序,它有一个3D组件,需要我能够旋转它。我在安卓资源网站上看到了这个例子 本示例不讨论绕z轴旋转。我已经尝试过使用四元数进行旋转,但我不知道如何获得围绕z轴的旋转 旋转某物后,轴不再相同(x,y),因此如何确定在哪个轴上旋转多少 我想知道是否有人能帮我学习如何绕着一个物体旋转。与上面的示例类似,但也围绕z轴。我已经花了大约24小时搜索并试图找出答案 更大的问题是,一旦你围绕y轴旋转90度,你怎么能检测到下一次旋转(在触

我是一名四年级计算机工程专业的学生,有一些安卓开发经验

我正在开发一个应用程序,它有一个3D组件,需要我能够旋转它。我在安卓资源网站上看到了这个例子

本示例不讨论绕z轴旋转。我已经尝试过使用四元数进行旋转,但我不知道如何获得围绕z轴的旋转

旋转某物后,轴不再相同(x,y),因此如何确定在哪个轴上旋转多少

我想知道是否有人能帮我学习如何绕着一个物体旋转。与上面的示例类似,但也围绕z轴。我已经花了大约24小时搜索并试图找出答案

更大的问题是,一旦你围绕y轴旋转90度,你怎么能检测到下一次旋转(在触摸屏上垂直移动)应该围绕z轴


提前谢谢你。

我建议你读这本书


特别是你的问题:参见第3.3.1部分,你也可以围绕中心旋转相机,而不是旋转物体。

你的问题不太正确。不要问“旋转某物后,轴不再相同(x,y),因此如何确定在哪个轴上旋转多少?”,而要问“如何围绕全局轴而不是局部轴旋转?”。您希望围绕全局x的旋转始终是围绕全局x的旋转,而不是围绕对象的局部x轴的旋转。你不会根据当前状态进行不同的旋转,你只需要改变你在概念上旋转的东西

首先,您可能正在存储,比如rotX、rotY和rotZ,并调用glRotatef应用旋转?这对你想做的还不够好。你要做的是用欧拉角来描述方向。您总是会遇到,其中一个轴的某些值会将其他两个轴转换为同一个轴。所以你失去了一定程度的自由。查看这篇文章以获得适当的解释

因为作为OpenGL编码器,您会非常满意它们,所以假设您将对象方向直接存储为一个称为M的矩阵。您将旋转存储为用于实现旋转的矩阵。没有明确的角度或轴的概念

假设你想绕x旋转。您可以围绕x轴生成一个合适的旋转矩阵,称之为R。这样的矩阵就是OpenGL在内部构建以执行glRotatef(角度,1,0,0)的矩阵

那么您实际上有两个选择-用MR替换M或用RM替换M。矩阵乘法是不可交换的,所以它们是不同的。就像使用OpenGL矩阵堆栈向左平移六个,然后旋转40度,产生的结果与旋转40度,然后向左平移六个不同

在本例中,R是对象,因此MR是后乘,RM是前乘。矩阵相乘创建一个矩阵,当应用于向量时,该矩阵的效果与应用第二个矩阵然后应用第一个矩阵的效果相同。因此,如果对其进行后乘运算,则得到的结果就像是将对象旋转了新的旋转,然后是之前的所有旋转。这显然是错误的做法。您希望新修改在迄今为止的所有其他修改之后生效。所以你是多重的。然后将结果存储为新的M

事实上,这就是全部。您可以明确地使用GL矩阵堆栈进行快速概念验证,如:

// ... I assume the modelview stack is active, M is an array of 16 floats ...

// ensure whatever's on the stack currently is kept safe
glPushMatrix();

    // but we don't actually care what it was, so load the identity
    glLoadIdentity();

    // build our rotation matrix first
    glRotatef(changeAroundX, 1, 0, 0);
    glRotatef(changeAroundY, 0, 1, 0);

    // multiply by M. OpenGL postmultiplies by the newer matrix, so this
    // is premultiplying M by whatever we just loaded
    glMultMatrixf(M);

    // read the new M back
    glGetFloatv(GL_MODELVIEW_MATRIX, M);

// and pretend we never touched the stack
glPopMatrix();

然后使用glMultMatrixf(M)代替glRotatef应用当前对象旋转。这只是一个概念的证明,因为你会很快在M中得到一些讨厌的数值错误,这仅仅是因为你对它进行了大量的操作。你可以一边修改M,但如果你已经有了四元数代码并且对它们感到满意,那么沿着这条路线走可能会更明智。只需将逻辑矩阵ops替换为四元数等价物。

将xAngle和yAngle添加到当前矩阵

Matrix.rotateM(matrix, 0, xAngleADD, matrix[1], matrix[5], matrix[9]);
Matrix.rotateM(matrix, 0, yAngleADD, matrix[0], matrix[4], matrix[8]);
gl.glMultMatrixf(matrix, 0);

Android目前没有glGetFloatv——你会用什么来代替它呢?在这种情况下,你可能需要自己编写一个快速的矩阵(或四元数或其他)数学。幸运的是,它相对容易-glRotate的手册页会准确地告诉您在每个单元格中填充什么来生成相关的矩阵,矩阵乘法很容易实现。谢谢。我试图跟随手册页,但最终的结果是,我可以任意更改立方体的旋转,但只能沿立方体的原始轴旋转。因此,如果我将立方体绕上下轴旋转180度,然后尝试将其向上旋转,它将向下旋转。我似乎缺少的关键部分是如何使用当前轴对旋转矩阵应用旋转。不幸的是,这是一个基本的数学背景错误。这就是乘法步骤的要点。将方向直接存储为矩阵。如果要添加旋转,请创建旋转矩阵。将存储的方向乘以旋转矩阵,然后再次存储。man页面对于旋转矩阵的标准公式来说是有用的。在5分钟内考虑使用UnyT3D来完成这项工作。(一旦你熟悉了它。)1,放入模型,2,放入“轨道”脚本。