matrix的适当乘法用于旋转/平移

任意点的旋转与平移

为了仅仅在xy平面上旋转/平移对象(仅在z轴上旋转和平移),而不仅仅是到全局中心(设备中心),还有其他任意点,我创build了一个algorithm,这是正确的我认为这是正确的), 但是在执行过程中需要花费大量的时间来移除一个不需要的翻译 (algorithm是在8月4日创build的,并且是在同一天实现的,因为代码已经被修改了15次)。

这里是http://www.pixdip.com/opengles/transform.php#ALGO1的实现

产生不需要的翻译的代码行在里面:

private static void updateModel(int upDown, float xAngle, float yAngle, float zAngle) {

如下所示:

  1. Matrix.multiplyMV(GLES20Renderer._uBodyCentreMatrix, 0, GLES20Renderer._ModelMatrixBody, 0, GLES20Renderer._uBodyCentre, 0);

  2. objX = GLES20Renderer._uBodyCentreMatrix[0];

  3. objY = GLES20Renderer._uBodyCentreMatrix[1];

即使进行了以下更改,沿着+ Y的不期望的翻译仍然存在:

  1. objY = _uBodyCentreMatrix[1] - _uBodyCentre[1];

  2. zAngle = 0;

  3. ds = 0;

在每次调用onDrawFrame() ,由于Renderer类的这些字段,值-0.545867f被添加到Y坐标:

private static final float[] _uBodyCentre = new float[]{-0.019683f, -0.545867f, -0.000409f, 1.0f};

protected static float[] _uBodyCentreMatrix = new float[4];

http://www.pixdip.com/opengles/transform.php#FIELDS

我需要帮助来理解为什么这种不需要的翻译发生,转换的确切错误,或者是错误的algorithm。

万向节锁可以成为一个问题吗?

请不要问我执行/练习更简单的例子,因为我已经准备好了Renderer类,用于关于全局z轴的旋转/平移,而且我正在使用的这个新任务在updateModel()

(请注意,所需的旋转仅在z轴上,只能在xy平面上平移)

[API 10-> 15]

实际的渲染器类有两个对象:炮塔(炮塔)和坦克主体 ,而炮塔(喷嘴)有不希望的向前平移,身体有不必要的向后平移

关于设备中心的翻译/旋转的Apk(在2.0中很容易制作): http ://www.pixdip.com/opengles/global.php

Apk翻译/旋转关于任意点(沿着+ Y有不需要的翻译): http : //www.pixdip.com/opengles/local.php

Apk的翻译/旋转关于任何点updateModel()被调用4次只: http ://www.pixdip.com/opengles/limited.php和所需的代码(这应该是足够的)在这里: http:// www.pixdip.com/opengles/code.php

目标物体(喷嘴/炮塔,物体)目前正在围绕它们自己的中心旋转,而不是物体的中心(这是_playerCentre),稍后我会对其进行修改。

我试图展示逻辑http://www.pixdip.com/opengles/images.php

看起来问题是:

 Matrix.multiplyMV(GLES20Renderer._uBodyCentreMatrix, 0, GLES20Renderer._ModelMatrixBody, 0, GLES20Renderer._uBodyCentre, 0); 

Matrix.multiplyMV是将4元素向量乘以4x4matrix并将结果存储在4元素列向量中的一种方法。 用matrix表示法:result = lhs x rhs。 如果resultVector元素与lhsMatrix或rhsVector元素重叠,则resultVector元素的值未定义。

我不认为你发布了所有的代码,所以我无法确定,但是根据“_uBodyCentreMatrix”的命名,你可能会遇到一个错误,因为它不是一个4元素的列向量。

我假设'_ModelMatrixBody'是一个4×4的matrix,'_uBodyCentre'是一个4元素的向量,否则这些也可能是有问题的。

你可以使用这样的方法:

 public void rotateToAbritrary(float[] arbitraryPoint, float xAngle, float yAngle, float zAngle) { Matrix.translateM(modelMatrix, 0, arbitraryPoint[0], arbitraryPoint[1], arbitraryPoint[2]); float max = Math.max(xAngle, Math.max(yAngle, zAngle)); if(max != 0.0f) Matrix.rotateM(modelMatrix, 0, max, xAngle / max, yAngle / max, zAngle / max); Matrix.translateM(modelMatrix, 0, -arbitraryPoint[0], -arbitraryPoint[1], -arbitraryPoint[2]); } 

我就是这么看的,至less,我让你去实施。 我收集你的代码不会受到Gimbal锁。

[已解决] java浮点错误是唯一的原因

M = T * I * T [inv]

没有产生一个单位matrix,所以不是使用Matrix.MultiplyMM

我inputmatrix之间的所有乘法

http://tutorialrandom.blogspot.com/2012/08/how-to-rotate-in-3d-using-opengl-proper.html

我觉得这是最简单的方法做旋转没有得到任何types的万向节锁或奇怪的翻译。 它是一个iOS的例子,但我肯定可以很容易地应用到Android。 它也适用于3d旋转,但是可以通过不绕其中一个轴旋转而很容易地应用到2D。