旋转矩阵Java
Rotation Matrix Java
我一直在学习创建游戏引擎的教程,当我开始计算 3D 旋转矩阵时,我 运行 遇到了一个问题,我认为矩阵计算不正确。当我尝试将矩阵在 x、y 和 z 轴上旋转 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
但我最终得到一个如下所示的矩阵:
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
编辑:经过更多调试后,我解决了矩阵 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;
}
而不是:
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;
}
我做了很多调试,我发现你有错误的索引:
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
希望对您有所帮助 ;)
我认为你的乘法函数在逻辑上是错误的。在您的乘法函数中,您最终将每个单元格的第一个原始数据和列相乘。如下所示将 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) 调试功能进行调试。您将一步步获得正确的执行思路,然后您将能够自己更正代码。
希望对您有所帮助。
我一直在学习创建游戏引擎的教程,当我开始计算 3D 旋转矩阵时,我 运行 遇到了一个问题,我认为矩阵计算不正确。当我尝试将矩阵在 x、y 和 z 轴上旋转 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
但我最终得到一个如下所示的矩阵:
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
编辑:经过更多调试后,我解决了矩阵 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;
}
而不是:
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;
}
我做了很多调试,我发现你有错误的索引:
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
希望对您有所帮助 ;)
我认为你的乘法函数在逻辑上是错误的。在您的乘法函数中,您最终将每个单元格的第一个原始数据和列相乘。如下所示将 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) 调试功能进行调试。您将一步步获得正确的执行思路,然后您将能够自己更正代码。
希望对您有所帮助。