轮换后翻译

我正在使用Android的OpenGL ES 2.0。 我正在使用触摸屏翻译和旋转模型。 我的翻译只在(x,y)平面上,而我的旋转只是围绕z轴。 想象一下,直接看一张桌子上的地图,然后移动到地图上的各种坐标上,并可以围绕您正在查看的点旋转地图。

问题在于,旋转后,我的后续翻译与屏幕上指针的运动更长,轴线不同。

我尝试过的所有东西都给了我两种行为之一一种相当于:

Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, Xposition, Yposition, 0.0f);
Matrix.rotateM(mModelMatrix, 0, rotationAngle, 0.0f, 0.0f, 1.0f);

这允许我按预期进行翻译(上/下屏幕上下移动模型,左/右移动模型左右),无论旋转如何。 问题在于旋转是围绕着对象的中心,我需要旋转是关于我正在看的点,这与对象的中心不同。

我可以得到的其他行为等同于:

Matrix.setIdentityM(mModelMatrix, 0);
Matrix.rotateM(mModelMatrix, 0, rotationAngle, 0.0f, 0.0f, 1.0f);
Matrix.translateM(mModelMatrix, 0, Xposition, Yposition, 0.0f);

这给了我想要的旋转,总是关于我正在看的点。 问题在于轮换后,翻译是错误的。 屏幕上的左/右沿着旋转的轴以不同的角度转换对象。

我需要一些方法来同时获得两种行为。 它需要围绕我正在看的点旋转, 沿着手指在屏幕上移动的方向进行平移。

这甚至有可能吗? 我基本上试图调和量子力学与牛顿物理学,注定要失败吗?

我不想列出我尝试过的所有技巧,因为我想用全新的视角来考虑所有可能性。

编辑:我仍然完全卡在这个。

我有一个以(0,0,0)世界坐标开始的对象。 我的观点是在物体上向下看z轴,我想限制翻译到x / y平面。 我也只想旋转关于z轴的对象。 旋转的中心必须始终是屏幕的中心。

我使用触摸屏控制翻译,因此无论旋转的方式如何,我都需要使用与手指移动方式相同的对象。

只要我旋转,我的所有翻译开始发生在旋转的坐标系上,这意味着对象不会随着指针在屏幕上移动。 我试着按照休·费希尔的建议做第二次翻译,但我无法弄清楚如何计算第二次翻译。 有另一种方法吗?


我有同样的问题。 不过,我使用C#与OpenGL(SharpGL)并使用旋转矩阵。

需要旋转后翻译才能将旋转点保持在屏幕中心。 作为CAD类型的应用程序。 问题是鼠标翻译并不总是与旋转后的屏幕平行。

我在这里找到了一个修复。

(Xposition, Yposition) = (Xposition, Yposition) + mRotation.transposed() * (XIncr, YIncr)

要么

NewTranslationPosition = oldTranslationPosition + rotationMatrix.Transposed * UserTranslationIncrement.

许多很多感谢reto.koradi(在OpenGL)!

所以我粗略地编码为3D:

double gXposition = 0;
double gYposition = 0;
double gZposition = 0;

double gXincr = 0;
double gYincr = 0;
double gZincr = 0;

float[] rotMatrix = new float[16]; //Rotational matrix

private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
{

  OpenGL gl = openGLControl.OpenGL;

  gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

  gl.LoadIdentity();
  gl.MultMatrix(rotMatrix); //This is my rotation, using a rotation matrix
  gl.Translate(gXposition, gYposition, gZposition); //translate second to keep rotation at center of screen

  DrawCube(ref  gl);

}

private void buttonTransLeft_Click(object sender, EventArgs e)
{
        double tX = -0.1;
        double tY = 0;
        double tZ = 0;

        TransposeRotMatrixFindPoint(ref tX, ref tY, ref tZ);

        gXposition = gXposition + tX;
        gYposition = gYposition + tY;
        gZposition = gZposition + tZ;

 }

 private void buttonTransRight_Click(object sender, EventArgs e)
 {

        double tX = 0.1;
        double tY = 0;
        double tZ = 0;

        TransposeRotMatrixFindPoint(ref tX, ref tY, ref tZ);


        gXposition = gXposition + tX;
        gYposition = gYposition + tY;
        gZposition = gZposition + tZ;

  }

public void TransposeRotMatrixFindPoint(ref double x, ref double y, ref double z)
    {
        //Multiply [x,y,z] by Transpose Rotation matrix to generate new [x,y,z]
        double Xt = 0; //Tempoary variable
        double Yt = 0; //Tempoary variable
        Xt = (x * rotMatrix[0, 0]) + (y * rotMatrix[0, 1]) + (z * rotMatrix[0, 2]);
        Yt = (x * rotMatrix[1, 0]) + (y * rotMatrix[1, 1]) + (z * rotMatrix[1, 2]);
        z = (x * rotMatrix[2, 0]) + (y * rotMatrix[2, 1]) + (z * rotMatrix[2, 2]);

        //or try this 
        //Xt = (x * rotMatrix[0, 0]) + (y * rotMatrix[1, 0]) + (z * rotMatrix[2, 0]);
        //Yt = (x * rotMatrix[0, 1]) + (y * rotMatrix[1, 1]) + (z * rotMatrix[2, 1]);
        //z = (x * rotMatrix[0, 2]) + (y * rotMatrix[1, 2]) + (z * rotMatrix[2, 2]);


        x = Xt;
        y = Yt;
    }

这是一个旧帖子,但我发布了最适合我后代的解决方案。

解决方案是保留一个单独的模型矩阵,它在发生时累积转换,并将每个转换乘以onDrawFrame()方法中的此矩阵。

//Initialize the model matrix for the current transformation
Matrix.setIdentityM(mModelMatrixCurrent, 0);
//Apply the current transformations
Matrix.translateM(mModelMatrixCurrent, 0, cameraX, cameraY, cameraZ);
Matrix.rotateM(mModelMatrixCurrent, 0, mAngle, 0.0f, 0.0f, 1.0f);
//Multiply the accumulated transformations by the current transformations
Matrix.multiplyMM(mTempMatrix, 0, mModelMatrixCurrent, 0, mModelMatrixAccumulated, 0);
System.arraycopy(mTempMatrix, 0, mModelMatrixAccumulated, 0, 16);

然后,累积的矩阵被用来定位对象。


以下是我如何思考翻译和旋转:您不移动对象,您正在移动坐标系的原点。 以这种方式思考,您需要对您的第一个行为进行额外的翻译。

手指运动是一种应该与屏幕XY轴对齐的平移,因此,您已经制定出来了,应该在旋转之前完成。 然后发生旋转,旋转该点周围物体的坐标系。 如果您希望将对象绘制到相对于该点的其他位置,则需要先执行另一个翻译以将原点移动到那里。

所以我认为你的最终序列应该是这样的

translate(dx,dy); 旋转(A); translate(cx,cy); 画()

其中cx和cy是地图中心与被观察点之间的距离。 (可能简化为-dx,-dy)

希望这可以帮助。

链接地址: http://www.djcxy.com/p/81821.html

上一篇: Translation after rotation

下一篇: iOS OpenGL ES 2.0 GLKit GLKMatrix4 Rotate after Touches Ended