Multiplication appropriée des matrices de rotation / translation

Rotation and Translation about arbitrary point

pour faire pivoter / traduire l'objet (rotation autour de l'axe z et translation uniquement dans le plan xy) pas seulement W. R. t to global center (device center) mais aussi W. R. t autres points arbitraires, j'ai créé un algorithme, qui est correct (parce que tous les codeurs principaux que j'ai discuté avec le considèrent comme correct),mais c'est prendre beaucoup de temps pour supprimer un indésirables de traduction dans l'implémentation (l'algorithme a été créé le Le code a été révisé 15 fois depuis le 4 août et est entré en vigueur le même jour.

Ici est la mise en œuvre http://www.pixdip.com/opengles/transform.php#ALGO1

les lignes de code qui produisent une traduction non désirée sont à l'intérieur:

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

et sont répertoriés ci-dessous:

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

  2. objX = GLES20Renderer._uBodyCentreMatrix[0];

  3. objY = GLES20Renderer._uBodyCentreMatrix[1];

non désirés traduction +Y persiste même si les modifications suivantes sont apportées:

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

  2. zAngle = 0;

  3. ds = 0;

La valeur -0.545867f est ajouté au Y coordonner les activités de chaque appel d' onDrawFrame(), à cause de ces champs de la classe Renderer:

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

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

<!--12http://www.pixdip.com/opengles/transform.php#FIELDS

j'ai besoin d'aide pour comprendre pourquoi ça indésirables traduction arriver, précisément ce qui est erroné avec les transformations, ou est-il de l'algorithme qui est faux.

Peut Gimbal lock être un question ici ?

s'il vous Plaît ne me demandez pas à effectuer de la pratique ou du plus simple des exemples, parce que j'ai préparé la classe de Rendu de rotation/translation globale de l'axe z, et cette nouvelle tâche que je suis en, utilise la même classe avec une légère modification dans la updateModel()

(veuillez noter que la rotation désirée n'est qu'environ l'axe z et la traduction seulement dans le plan xy)

[API 10 - >15]

la classe Renderer réelle a deux objets: tourelle de réservoir (buse) et corps de réservoir, alors que la tourelle (buse) a une translation vers l'avant non désirée, le corps a une translation vers l'arrière non désirée

Apk for translation/rotation sur device center (qui est facile à faire dans opengles 2.0): http://www.pixdip.com/opengles/global.php

Apk for translation/rotation sur les points arbitraires (ce qui est indésirable translation le long de +Y): http://www.pixdip.com/opengles/local.php

Apk pour translation / rotation sur des points arbitraires dans lesquels updateModel () est appelé 4 fois seulement: http://www.pixdip.com/opengles/limited.php et code requis (ce qui devrait être suffisant) est ici: http://www.pixdip.com/opengles/code.php

les parties de l'objet (buse/tourelle,corps) tournent actuellement autour de leur propre centre et non du centre de l'objet (qui est _playerCentre), je modifierai cela plus tard.

j'ai essayé de démontrer la logique http://www.pixdip.com/opengles/images.php

19
demandé sur GLES 2012-08-15 11:33:56

4 réponses

on dirait que le problème est:

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

de la Matrice.multiplyMV est une méthode pour multiplier un vecteur de 4 éléments par une matrice 4x4 et stocker le résultat dans un vecteur de colonne de 4 éléments. En notation matricielle: résultat = lhs x rhs. Les valeurs de l'élément resultVector ne sont pas définies si les éléments resultVector chevauchent les éléments lhsMatrix ou rhsVector.

je ne pense pas que vous avez posté, tout le code donc je ne peux pas vérifier pour vous, mais à en juger par votre appellation de "_uBodyCentreMatrix' vous sont probablement confrontés à une erreur parce qu'il ne s'agit pas d'un vecteur de colonne à 4 éléments.

je suppose que '_ModelMatrixBody' est une matrice 4x4 et '_uBodyCentre' est un vecteur 4 éléments, sinon ceux-ci pourraient aussi être problématiques.

5
répondu Joseph Lormand 2012-08-24 07:05:26

[résolu] les erreurs java floating point étaient la seule cause

M = T * I * T [inv]

n'a pas donné lieu à une matrice d'identité, donc au lieu d'utiliser Matrix.MultiplyMM

je tape toutes les multiplications entre les matrices

4
répondu GLES 2012-11-25 10:31:14

Vous pouvez utiliser une méthode comme ceci:

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

C'est comme ça que je le vois, au moins, je vous laisse à l'implémentation. Je déduis de votre code de ne pas subir le Gimbal lock.

3
répondu dragostis 2012-08-22 17:30:35

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

je trouve que c'est la façon la plus simple de faire des rotations sans avoir aucune sorte de blocage de cardan ou de traduction étrange. c'est un exemple iOS mais im sure peut être appliqué facilement à android. Aussi ses pour les rotations 3d mais peut facilement être appliqué à 2d en ne tournant tout simplement pas sur l'un des axes.

3
répondu Fonix 2012-08-23 15:07:09