2016-04-19 3 views
-2

Я слежу за учебным пособием по созданию игрового движка, и когда мне нужно вычислить матрицу 3D-поворота, я столкнулся с проблемой, что, по-моему, матрица не вычисляется должным образом. Когда я пытаюсь повернуть матрицу на 0 градусов по х, у, а ось г, я должен получать единичную матрицу для матрицы вращения, которая должна выглядеть следующим образом:Матрица вращения Java

Rotation Matrix: 

1.0 0.0 0.0 0.0 
0.0 1.0 0.0 0.0 
0.0 0.0 1.0 0.0 
0.0 0.0 0.0 1.0 

, но я в конечном итоге с матрица, которая выглядит следующим образом:

Rotation Matrix: 

1.0 1.0 1.0 1.0 
1.0 1.0 1.0 1.0 
1.0 1.0 1.0 1.0 
1.0 1.0 1.0 1.0 

Вот код для вычисления матрицы вращения непосредственно из учебника:

public class Matrix4f 
{ 
    private float[][] m; 

    //generate a 4X4 array as my inital matrix which will represent homogeneous 
    //coordinates: x, y, z, w 
    public Matrix4f() 
    { 
     m = new float[4][4]; 
    } 

    public Matrix4f initRotation(float x, float y, float z) 
    { 
     //generate rotation matrices for x, y, and z 
     Matrix4f rx = new Matrix4f(); 
     Matrix4f ry = new Matrix4f(); 
     Matrix4f rz = new Matrix4f(); 

     //convert x,y, and z to radians for angle calculations 
     x = (float)Math.toRadians(x); 
     y = (float)Math.toRadians(y); 
     z = (float)Math.toRadians(z); 

     //calculate rotation matrices for x, y, z 

     rz.m[0][0] = (float)Math.cos(z);rz.m[0][1] = (float)Math.sin(z);rz.m[0][2] = 0;    rz.m[0][3] = 0; 
     rz.m[1][0] = -(float)Math.sin(z);rz.m[1][1] = (float)Math.cos(z);rz.m[1][2] = 0;     rz.m[1][3] = 0; 
     rz.m[2][0] = 0;     rz.m[2][1] = 0;     rz.m[2][2] = 1;     rz.m[2][3] = 0; 
     rz.m[3][0] = 0;     rz.m[3][1] = 0;     rz.m[3][2] = 0;     rz.m[3][3] = 1; 

     rx.m[0][0] = 1;     rx.m[0][1] = 0;     rx.m[0][2] = 0;     rx.m[0][3] = 0; 
     rx.m[1][0] = 0;     rx.m[1][1] = (float)Math.cos(x);rx.m[1][2] = -(float)Math.sin(x);rx.m[1][3] = 0; 
     rx.m[2][0] = 0;     rx.m[2][1] = -(float)Math.sin(x);rx.m[2][2] = (float)Math.cos(x);rx.m[2][3] = 0; 
     rx.m[3][0] = 0;     rx.m[3][1] = 0;     rx.m[3][2] = 0;     rx.m[3][3] = 1; 

     ry.m[0][0] = (float)Math.cos(y);ry.m[0][1] = 0;     ry.m[0][2] = -(float)Math.sin(y);ry.m[0][3] = 0; 
     ry.m[1][0] = 0;     ry.m[1][1] = 1;     ry.m[1][2] = 0;     ry.m[1][3] = 0; 
     ry.m[2][0] = (float)Math.sin(y);ry.m[2][1] = 0;     ry.m[2][2] = (float)Math.cos(y);ry.m[2][3] = 0; 
     ry.m[3][0] = 0;     ry.m[3][1] = 0;     ry.m[3][2] = 0;     ry.m[3][3] = 1; 

     //calculate the final rotation matrix by multiplying the 3 rotation matrices together 
     m = rz.mul(ry.mul(rx)).getM(); 

     //a simple way to print out the full matrix 
     System.out.println("Rotation Matrix:"); 
     for(int i = 0; i < 4; i++) 
     { 
      System.out.println(""); 
      for(int j = 0; j < 4; j++) 
      { 
       System.out.print(m[i][j] + " "); 
      } 
     } 
     System.out.println(""); 

     return this; 
    } 

    //defining the multiplication operation for matrices 
    public Matrix4f mul(Matrix4f r) 
    { 
     Matrix4f res = new Matrix4f(); 

     for(int i = 0; i < 4; i++) 
     { 
      for(int j = 0; j < 4; j++) 
      { 
       res.set(i, j, m[i][0]*r.get(0, i) + 
           m[i][1]*r.get(1, i) + 
           m[i][2]*r.get(2, i) + 
           m[i][3]*r.get(3, i)); 
      } 
     } 

     return res; 

    } 

    //get the matrix in array form 
    public float[][] getM() 
    { 
     return m; 
    } 

    //get an individual element of the matrix 
    public float get(int x, int y) 
    { 
     return m[x][y]; 
    } 

    //set the whole matrix equal to a matrix m 
    public void setM(float[][] m) 
    { 
     this.m = m; 
    } 

    //set an individual element of the matrix to a value 
    public void set(int x, int y, float value) 
    { 
     m[x][y] = value; 
    } 

} 

Тогда в основном, когда я пытаюсь запустить его в основном методе, как так :

(new Matrix4f()).initRotation(0, 0, 0); 

я

Rotation Matrix: 

1.0 1.0 1.0 1.0 
1.0 1.0 1.0 1.0 
1.0 1.0 1.0 1.0 
1.0 1.0 1.0 1.0 

Даже если в соответствии с матрицей вращения операций я должен получать:

Rotation Matrix: 

1.0 0.0 0.0 0.0 
0.0 1.0 0.0 0.0 
0.0 0.0 1.0 0.0 
0.0 0.0 0.0 1.0 

EDIT: После того, как еще некоторые отладки, я решил проблему после больше отладки будет проблемой в методе матрицы mul. Прошу прощения за свою лень. Я программировал какое-то время, и я действительно часто не занимаюсь этим, но я просто очень расстроился в своей программе.

коррекции для алгоритма матричного умножения является:

public Matrix4f mul(Matrix4f r) 
    { 
     Matrix4f res = new Matrix4f(); 

     for(int i = 0; i < 4; i++) 
     { 
      for(int j = 0; j < 4; j++) 
      { 
       res.set(i, j, m[i][0]*r.get(0, j) + 
           m[i][1]*r.get(1, j) + 
           m[i][2]*r.get(2, j) + 
           m[i][3]*r.get(3, j)); 
      } 
     } 

     return res; 

    } 

вместо:

общественных Matrix4f мул (Matrix4f г) { Matrix4f Рез = новый Matrix4f();

for(int i = 0; i < 4; i++) 
    { 
     for(int j = 0; j < 4; j++) 
     { 
      res.set(i, j, m[i][0]*r.get(0, i) + 
          m[i][1]*r.get(1, i) + 
          m[i][2]*r.get(2, i) + 
          m[i][3]*r.get(3, i)); 
     } 
    } 

    return res; 

} 
+0

Вы должны выполнить некоторую отладку. –

+0

Я сделал тонну отладки. Какую еще информацию вы хотите? Я был бы рад предоставить его. –

+0

Вы должны иметь возможность идентифицировать расчет/строку, в которой поведение отклоняется от ожиданий, а затем построить [минимальный тестовый сценарий] (http://stackoverflow.com/help/mcve). –

ответ

2
  • Я думаю, что функция умножения неверна логически. В вашей функции умножения вы получаете умножение первого сырых и столбцов для каждой ячейки. изменение i на j, как показано ниже, будет правильно вычислять умножение.

    public Matrix4f mul(Matrix4f r) { 
    Matrix4f res = new Matrix4f(); 
    for(int i = 0; i < 4; i++) 
    { 
        for(int j = 0; j < 4; j++) 
        { 
         res.set(i, j, m[i][0]*r.get(0, j) + 
             m[i][1]*r.get(1, j) + 
             m[i][2]*r.get(2, j) + 
             m[i][3]*r.get(3, j)); 
        } 
    } 
    
    return res; 
    
    } 
    
  • Во-вторых, вы можете попробовать выполнить отладку кода с помощью контрольных точек в функции умножения. Вы можете выполнить отладку с помощью любой стандартной функции отладки IDE (Eclipse). Вы получите правильное представление об исполнении шаг за шагом, и тогда вы сможете исправить код самостоятельно.

Надеюсь, это поможет.

+0

Выстроено так же, как и я +1 – maskacovnik

1

Я сделал много отладки, и я понял, у вас есть плохие показатели:

res.set(i, j, m[i][0]*r.get(0, i) + 
    m[i][1]*r.get(1, i) + 
    m[i][2]*r.get(2, i) + 
    m[i][3]*r.get(3, i)); 

У вас есть индекс i на обеих матриц - вы должны исправить это следующим образом:

res.set(i, j, m[i][0]*r.get(0, j) + 
    m[i][1]*r.get(1, j) + 
    m[i][2]*r.get(2, j) + 
    m[i][3]*r.get(3, j)); 

Если вы получили транспонированную матрицу в следующих расчетах (на идентификационной матрице нет способа ее выяснить) - обмен i и j Надеюсь, что это поможет;)

Смежные вопросы