简体   繁体   English

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

[英]Appropriate multiplication of matrices for rotation/translation

关于任意点的旋转和平移

In order to rotate/translate object (rotation only about z-axis and translation only in xy plane) not just wrt to global center (device center) but also wrt other arbitrary points, I created an algorithm, which is correct (because all senior coders I have discussed with consider it correct), but it is taking a lot of time to remove an undesired translation in the implementation (algorithm was created on August 4 and was implemented on the same day, since then the code has been revised 15 times). 为了旋转/平移物体(仅绕z轴旋转和仅在xy平面上平移)不仅仅是wrt到全局中心(设备中心)而且还有其他任意点,我创建了一个算法,这是正确的(因为所有高级我已经讨论过的编码器认为它是正确的), 但是在实现中删除不需要的翻译需要花费很多时间(算法是在8月4日创建的,并且是在同一天实现的,从那以后代码被修改了15次)。

Here is the implementation http://www.pixdip.com/opengles/transform.php#ALGO1 这是http://www.pixdip.com/opengles/transform.php#ALGO1的实现

The lines of code that are producing undesired translation are inside: 产生不希望的翻译的代码行在里面:

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

and are listed below: 并列出如下:

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

  2. objX = GLES20Renderer._uBodyCentreMatrix[0];

  3. objY = GLES20Renderer._uBodyCentreMatrix[1];

The undesired translation along +Y persists even if the following changes are made: 即使进行了以下更改,沿着+ Y的不期望的转换仍然存在:

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

  2. zAngle = 0;

  3. ds = 0;

The value -0.545867f is added to the Y coordinate on every call to onDrawFrame() , because of these fields of the Renderer class: 每次调用onDrawFrame() ,值-0.545867f都会添加到Y坐标,因为Renderer类的这些字段:

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

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

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

I need help to understand why does that undesired translation happen, what is exactly wrong with the transformations, or is it the algorithm that is wrong. 我需要帮助才能理解为什么不希望的翻译发生,转换的确切错误,或者算法是错误的。

Can Gimbal lock be an issue here ? 万向锁可以成为一个问题吗?

Please do not ask me to perform/practice simpler examples, because I have prepared the Renderer class for rotation/translation about global z-axis, and this new task that I am into, uses the same class with slight modification in updateModel() 请不要让我执行/练习更简单的示例,因为我准备了Renderer类来进行关于全局z轴的旋转/转换,而我所进入的这个新任务在updateModel()使用相同的类稍作修改

(Please note that the desired rotation is only about z-axis and translation only in xy plane) (请注意,所需的旋转仅约为z轴,仅在xy平面内平移)

[API 10->15] [API 10-> 15]

The actual Renderer class has two objects: tank turret(nozzle) and tank body , while turret(nozzle) has undesired forward translation, the body has undesired backward translation 实际的渲染器类有两个对象:坦克炮塔(喷嘴)和坦克体 ,而炮塔(喷嘴)有不希望的向前平移,身体有不希望的向后平移

Apk for translation/rotation about device center (which is easy to make in opengles 2.0): http://www.pixdip.com/opengles/global.php 关于设备中心翻译/轮换的Apk(在opengles 2.0中很容易制作): http ://www.pixdip.com/opengles/global.php

Apk for translation/rotation about arbitrary points (which has undesired translation along +Y): http://www.pixdip.com/opengles/local.php 关于任意点的翻译/旋转的Apk(沿+ Y有不希望的翻译): http//www.pixdip.com/opengles/local.php

Apk for translation/rotation about arbitrary points in which updateModel() is called 4 times only: http://www.pixdip.com/opengles/limited.php and required code (which should be sufficient) is here: http://www.pixdip.com/opengles/code.php apk用于翻译/轮换任意点,其中up​​dateModel()仅被调用4次: http ://www.pixdip.com/opengles/limited.php和所需代码(应该足够)在这里: http:// www.pixdip.com/opengles/code.php

Parts of object (nozzle/turret,body) are currently rotating about their own centres not the centre of object (which is _playerCentre), I will modify that later. 物体的一部分(喷嘴/炮塔,车身)目前正在围绕它们自己的中心而不是物体的中心(这是_playerCentre)旋转,我稍后会修改它。

I have tried to demonstrate logic http://www.pixdip.com/opengles/images.php 我试图演示逻辑http://www.pixdip.com/opengles/images.php

It looks like the problem is: 看起来问题是:

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

Matrix.multiplyMV is a method to multiply a 4 element vector by a 4x4 matrix and store the result in a 4 element column vector. Matrix.multiplyMV是一种将4元素向量乘以4x4矩阵并将结果存储在4元素列向量中的方法。 In matrix notation: result = lhs x rhs. 在矩阵表示法中:result = lhs x rhs。 The resultVector element values are undefined if the resultVector elements overlap either the lhsMatrix or rhsVector elements. 如果resultVector元素与lhsMatrix或rhsVector元素重叠,则resultVector元素值是未定义的。

I don't think you posted all the code so I can't check for sure, but judging by your naming of '_uBodyCentreMatrix' you are probably encountering an error because it is not a 4 element column vector. 我不认为你发布了所有代码,所以我无法确认,但是根据你的'_BodyCentreMatrix'的命名判断你可能遇到错误,因为它不是4元素列向量。

I'm assuming that '_ModelMatrixBody' is a 4x4 matrix and '_uBodyCentre' is a 4 element vector, otherwise these could be problematic as well. 我假设'_ModelMatrixBody'是4x4矩阵,'_uBodyCentre'是4元素向量,否则这些也可能有问题。

[SOLVED] java floating point errors were the only cause [求助] java浮点错误是唯一的原因

M = T * I * T[inv] M = T * I * T [inv]

did not result into an identity matrix, so instead of using Matrix.MultiplyMM 没有导致身份矩阵,所以不使用Matrix.MultiplyMM

I type all the multiplications between the matrices 我输入矩阵之间的所有乘法

You could use a method like this: 你可以使用这样的方法:

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

That's how I see it, at least, I leave you to the implementation. 这就是我的看法,至少,我让你参与实施。 I gather your code doesn't suffer the Gimbal lock. 我收集你的代码不受Gimbal锁定。

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

I find this the simplest way to do rotations without getting any sort of gimbal lock or odd translation. 我发现这是最简单的旋转方式而不会获得任何类型的万向节锁定或奇怪的翻译。 its an iOS example but im sure can be applied easily to android. 它是一个iOS示例,但我肯定可以很容易地应用到Android。 Also its for 3d rotations but can easily be applied to 2d by just not rotating about one of the axis. 它也适用于三维旋转,但只需绕一个轴旋转即可轻松应用于2d。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM