我正在为 Android 使用 OpenGL ES 2.0。我正在使用触摸屏平移和旋转模型。我的平移仅在 (x, y) 平面内,我的旋转仅围绕 z 轴。想象一下,直接向下看 table 上的 map 并移动到 map 上的各个坐标,并且能够围绕您正在查看的点旋转 map 。
问题是在我旋转之后,我的后续平移将不再与屏幕上指针的运动相匹配,轴不同。
我尝试过的一切都给了我两种行为之一一种相当于:
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) 开始。我的 View 是从对象的 z 轴向下看,我想将平移限制在 x/y 平面上。我还想仅围绕 z 轴旋转对象。旋转的中心必须始终是屏幕的中心。
我正在使用触摸屏控制平移,因此无论手指如何旋转,我都需要对象以与手指移动相同的方式移动。
一旦我旋转,我所有的平移就开始在旋转坐标系上发生,这意味着对象不会随着屏幕上的指针移动。我试过按照 Hugh Fisher 的建议进行第二次翻译,但我不知道如何计算第二次翻译。还有别的办法吗?
最佳答案
我遇到了同样的问题。但是我使用 C# 和 OpenGL (SharpGL) 并使用旋转矩阵。
旋转后的平移需要保持旋转点在屏幕中心。 作为 CAD 类型的应用程序。 问题是鼠标平移在旋转后并不总是与屏幕平行。
我找到了修复 here .
(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;
}
关于android - 旋转后平移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22444310/