矩阵的旋转/平移的适当乘法(Appropriate multiplication of matric

2019-06-17 17:34发布

为了旋转/翻译对象(只有Z轴,且只能在XY平面平移旋转)不只是WRT全球中心(装置中心),而且WRT其他任意点,我创建了一个算法,这是正确的(因为所有高级我曾与讨论程序员认为这是正确的), 它采取了大量的时间在执行删除不需要的翻译 (算法在8月4日创建,并于同日开始实施,从此代码已修订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;

该值-0.545867f被添加到Y在每次调用协调onDrawFrame()因为渲染器类的这些字段:

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

我需要帮助理解为什么是不需要翻译发生,究竟是什么毛病转换,或者是它,这是错误的算法。

万向锁可以是一个问题吗?

请不要问我执行/练习简单的例子,因为我已准备就绪,旋转/平移对全球z轴,而我到这个新任务的渲染器类,使用稍加修改的同一类updateModel()

(请注意,所需转动大约只有z轴,且只能在XY平面转换)

[API 10-> 15]

实际渲染器类有两个对象:罐炮塔(喷嘴)和罐身 ,而转塔(喷嘴)具有不期望的向前平移,所述主体具有不期望的向后平移

APK翻译/绕设备中心(这是很容易在opengles 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

Answer 1:

它看起来像问题是:

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

Matrix.multiplyMV是乘以一个4×4矩阵4元素矢量,并将结果存储在4族元素的列向量的方法。 在矩阵表示法:结果= LHS X RHS。 所述resultVector元素值是不确定的,如果resultVector元素重叠要么lhsMatrix或rhsVector元件。

我不认为你发布的所有代码,所以我无法检查确定,而是由你的“_uBodyCentreMatrix”的命名来看你可能遇到一个错误,因为它不是一个4元列向量。

我假定“_ModelMatrixBody”是4×4矩阵,并且“_uBodyCentre”是4元素矢量,否则这些可能是有问题的为好。



Answer 2:

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

M = T * I * T [INV]

没有导致到一个单位矩阵,因此而不是使用Matrix.MultiplyMM

我键入所有矩阵之间的乘法



Answer 3:

你可以使用这样的方法:

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]);
}

这就是我看到它,至少,我离开你的落实。 我收集你的代码不会遭受万向锁。



Answer 4:

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

我这才发觉做旋转没有得到任何形式的万向节锁定或奇数翻译的最简单的方法。 其在iOS的例子,但我肯定可以很容易地应用到Android。 其还用于3D旋转,但可以很容易地应用于通过只是没有绕轴的一个至2d。



文章来源: Appropriate multiplication of matrices for rotation/translation