Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appropriate multiplication of matrices for rotation/translation

Rotation and Translation about arbitrary point

In order to rotate/translate object (rotation only about z-axis and translation only in xy plane) not just w.r.t to global center (device center) but also w.r.t 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).

Here is the implementation 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:

  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:

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

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()

(Please note that the desired rotation is only about z-axis and translation only in xy plane)

[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 for translation/rotation about arbitrary points (which has undesired translation along +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

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.

I have tried to demonstrate logic http://www.pixdip.com/opengles/images.php

like image 920
Patt Mehta Avatar asked Aug 15 '12 07:08

Patt Mehta


People also ask

How do you combine translation and rotation matrix?

A rotation matrix and a translation matrix can be combined into a single matrix as follows, where the r's in the upper-left 3-by-3 matrix form a rotation and p, q and r form a translation vector. This matrix represents rotations followed by a translation.

What is the transformation matrix for rotation?

A rotation matrix can be defined as a transformation matrix that operates on a vector and produces a rotated vector such that the coordinate axes always remain fixed. These matrices rotate a vector in the counterclockwise direction by an angle θ. A rotation matrix is always a square matrix with real entities.

What are 4x4 matrices used for?

The 4 by 4 transformation matrix uses homogeneous coordinates, which allow to distinguish between points and vectors. Vectors have a direction and magnitude whereas points are positions specified by 3 coordinates with respect to the origin and three base vectors i, j and k that are stored in the first three columns.


1 Answers

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. In matrix notation: result = lhs x rhs. The resultVector element values are undefined if the resultVector elements overlap either the lhsMatrix or rhsVector elements.

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.

I'm assuming that '_ModelMatrixBody' is a 4x4 matrix and '_uBodyCentre' is a 4 element vector, otherwise these could be problematic as well.

like image 61
Joseph Lormand Avatar answered Nov 16 '22 01:11

Joseph Lormand