我使用Java和OpenGL(LWJGL)来设置一些矩阵,我不想使用内置的方法,因为我也想在Android上工作,所以使用LWJGL的矩阵类是不合适的。目前我正在建立一个透视图,使用一个视场70,znear 0.1,zfar 1000。使用当前设置旋转只会导致奇怪的结果,不是以正确的方式旋转,对象被奇怪地缩放,经常消失。
下面是Matrix4D类:
public class Matrix4D {
/* The values within this matrix */
public float[] values;
/* The default constructor */
public Matrix4D() {
//Create the values
this.values = new float[16];
}
/* The constructor with the values given */
public Matrix4D(float[] values) {
//Create the values
this.values = values;
}
/* The constructor with the values given */
public Matrix4D(float[][] values) {
//Load the values
load(values);
}
/* The method used to set the values given a 2 dimensional array */
public void load(float[][] values) {
this.values = new float[] {
values[0][0], values[0][1], values[0][2], values[0][3],
values[1][0], values[1][1], values[1][2], values[1][3],
values[2][0], values[2][1], values[2][2], values[2][3],
values[3][0], values[3][1], values[3][2], values[3][3]
};
}
/* The method used to get a value using the coordinate within this matrix */
public float get(int x, int y) {
//Get the position
int position = x + (y * 4);
//Return the value
return this.values[position];
}
/* The method used to return a string representation of this matrix */
public String toString() {
//Return the string
return "[ " + this.values[0] + " " + this.values[1] + " " + + this.values[2] + " " + + this.values[3] + " ]" + "\n" +
"[ " + this.values[4] + " " + this.values[5] + " " + + this.values[6] + " " + + this.values[7] + " ]" + "\n" +
"[ " + this.values[8] + " " + this.values[9] + " " + + this.values[10] + " " + + this.values[11] + " ]" + "\n" +
"[ " + this.values[12] + " " + this.values[13] + " " + + this.values[14] + " " + + this.values[15] + " ]";
}
/* The method used to get the values */
public float[] getValues() { return this.values; }
/* The method used to get the values in a 2D array */
public float[][] getValues2DArray() {
//The array
float[][] array = new float[4][4];
//Go through each value
int column = 0;
int row = 0;
while (column * row < array.length) {
row ++;
if (row >= 4) {
column++;
row = 0;
}
array[column][row] = this.values[column * row];
}
//Return the array
return array;
}
}
下面是Matrix类(用于在矩阵上设置和执行计算):
public class Matrix {
/* The different matrices */
public static Matrix4D modelMatrix = new Matrix4D();
public static Matrix4D viewMatrix = new Matrix4D();
public static Matrix4D projectionMatrix = new Matrix4D();
public static Matrix4D modelViewProjectionMatrix = new Matrix4D();
/* The static method used to load an identity matrix */
public static void loadIdentity(Matrix4D matrix) {
//Load the identity matrix
matrix.load(new float[][] {
new float[] { 1, 0, 0, 0 },
new float[] { 0, 1, 0, 0 },
new float[] { 0, 0, 1, 0 },
new float[] { 0, 0, 0, 1 },
});
}
/* The static method used to add two matrices together */
public static Matrix4D add(Matrix4D matrixA, Matrix4D matrixB) {
//Create a new matrix
Matrix4D matrix = new Matrix4D();
//Go through each value
for (int a = 0; a < matrix.values.length; a++)
//Assign the current value
matrix.values[a] = matrixA.values[a] + matrixB.values[a];
//Return the matrix
return matrix;
}
/* The static method used to subtract a matrix (B) from another (A) */
public static Matrix4D subtract(Matrix4D matrixA, Matrix4D matrixB) {
//Create a new matrix
Matrix4D matrix = new Matrix4D();
//Go through each value
for (int a = 0; a < matrix.values.length; a++)
//Assign the current value
matrix.values[a] = matrixB.values[a] - matrixA.values[a];
//Return the matrix
return matrix;
}
/* The static method used to multiply two matrices together */
public static Matrix4D multiply(Matrix4D matrixA, Matrix4D matrixB) {
//Create a new matrix
Matrix4D matrix = new Matrix4D(new float[][] {
new float[] {
(matrixA.values[0] * matrixB.values[0]) + (matrixA.values[1] * matrixB.values[4]) + (matrixA.values[2] * matrixB.values[8]) + (matrixA.values[3] * matrixB.values[12]),
(matrixA.values[0] * matrixB.values[1]) + (matrixA.values[1] * matrixB.values[5]) + (matrixA.values[2] * matrixB.values[9]) + (matrixA.values[3] * matrixB.values[13]),
(matrixA.values[0] * matrixB.values[2]) + (matrixA.values[1] * matrixB.values[6]) + (matrixA.values[2] * matrixB.values[10]) + (matrixA.values[3] * matrixB.values[14]),
(matrixA.values[0] * matrixB.values[3]) + (matrixA.values[1] * matrixB.values[7]) + (matrixA.values[2] * matrixB.values[11]) + (matrixA.values[3] * matrixB.values[15])
},
new float[] {
(matrixA.values[4] * matrixB.values[0]) + (matrixA.values[5] * matrixB.values[4]) + (matrixA.values[6] * matrixB.values[8]) + (matrixA.values[7] * matrixB.values[12]),
(matrixA.values[4] * matrixB.values[1]) + (matrixA.values[5] * matrixB.values[5]) + (matrixA.values[6] * matrixB.values[9]) + (matrixA.values[7] * matrixB.values[13]),
(matrixA.values[4] * matrixB.values[2]) + (matrixA.values[5] * matrixB.values[6]) + (matrixA.values[6] * matrixB.values[10]) + (matrixA.values[7] * matrixB.values[14]),
(matrixA.values[4] * matrixB.values[3]) + (matrixA.values[5] * matrixB.values[7]) + (matrixA.values[6] * matrixB.values[11]) + (matrixA.values[7] * matrixB.values[15])
},
new float[] {
(matrixA.values[8] * matrixB.values[0]) + (matrixA.values[9] * matrixB.values[4]) + (matrixA.values[10] * matrixB.values[8]) + (matrixA.values[11] * matrixB.values[12]),
(matrixA.values[8] * matrixB.values[1]) + (matrixA.values[9] * matrixB.values[5]) + (matrixA.values[10] * matrixB.values[9]) + (matrixA.values[11] * matrixB.values[13]),
(matrixA.values[8] * matrixB.values[2]) + (matrixA.values[9] * matrixB.values[6]) + (matrixA.values[10] * matrixB.values[10]) + (matrixA.values[11] * matrixB.values[14]),
(matrixA.values[8] * matrixB.values[3]) + (matrixA.values[9] * matrixB.values[7]) + (matrixA.values[10] * matrixB.values[11]) + (matrixA.values[11] * matrixB.values[15])
},
new float[] {
(matrixA.values[12] * matrixB.values[0]) + (matrixA.values[13] * matrixB.values[4]) + (matrixA.values[14] * matrixB.values[8]) + (matrixA.values[15] * matrixB.values[12]),
(matrixA.values[12] * matrixB.values[1]) + (matrixA.values[13] * matrixB.values[5]) + (matrixA.values[14] * matrixB.values[9]) + (matrixA.values[15] * matrixB.values[13]),
(matrixA.values[12] * matrixB.values[2]) + (matrixA.values[13] * matrixB.values[6]) + (matrixA.values[14] * matrixB.values[10]) + (matrixA.values[15] * matrixB.values[14]),
(matrixA.values[12] * matrixB.values[3]) + (matrixA.values[13] * matrixB.values[7]) + (matrixA.values[14] * matrixB.values[11]) + (matrixA.values[15] * matrixB.values[15])
}
});
//Return the matrix
return matrix;
}
/* The static method used to transpose a matrix */
public static Matrix4D transpose(Matrix4D matrix) {
//Get the values from the matrix
float[][] values = matrix.getValues2DArray();
//The new values
float[][] newValues = new float[4][4];
//Go through the array
for (int y = 0; y < values.length; y++) {
for (int x = 0; x < values[y].length; x++) {
//Assign the new value
newValues[x][y] = values[y][x];
}
}
//Return the matrix
return new Matrix4D(newValues);
}
/* The static method used to translate a matrix */
public static Matrix4D translate(Matrix4D matrix, Vector3D vector) {
//The transform matrix
Matrix4D transform = new Matrix4D(new float[][] {
new float[] { 0, 0, 0, vector.x },
new float[] { 0, 0, 0, vector.y },
new float[] { 0, 0, 0, vector.z },
new float[] { 0, 0, 0, 0 },
});
//Add onto the matrix and return the result
return add(matrix, transform);
}
/* The static method used to rotate a matrix */
public static Matrix4D rotate(Matrix4D matrix, float angle, int x, int y, int z) {
//The transform matrix
Matrix4D transform = new Matrix4D();
//Calculate the values needed
float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle);
//Check the x y and z values
if (x == 1) {
transform.load(new float[][] {
new float[] { 0, 0, 0, 0 },
new float[] { 0, cos, -sin, 0 },
new float[] { 0, sin, cos, 0 },
new float[] { 0, 0, 0, 0 },
});
} else if (y == 1) {
transform.load(new float[][] {
new float[] { cos, 0, sin, 0 },
new float[] { 0, 0, 0, 0 },
new float[] { -sin, 0, cos, 0 },
new float[] { 0, 0, 0, 0 },
});
} else if (z == 1) {
transform.load(new float[][] {
new float[] { cos, -sin, 0, 0 },
new float[] { sin, cos, 0, 0 },
new float[] { 0, 0, 0, 0 },
new float[] { 0, 0, 0, 0 },
});
}
//Add onto the matrix and return the result
return add(matrix, transform);
}
/* The static method used to scale a matrix */
public static Matrix4D scale(Matrix4D matrix, Vector3D vector) {
//The transform matrix
Matrix4D transform = new Matrix4D(new float[][] {
new float[] { vector.x, 0, 0, 0 },
new float[] { 0, vector.y, 0, 0 },
new float[] { 0, 0, vector.z, 0 },
new float[] { 0, 0, 0, 0 },
});
//Add onto the matrix and return the result
return add(matrix, transform);
}
/* The static method used to return an orthographic projection matrix */
public static Matrix4D ortho(float left, float right, float top, float bottom, float zfar, float znear) {
return new Matrix4D(new float[][] {
new float[] { 2 / (right - left), 0, 0, -((right + left) / (right - left)) },
new float[] { 0, 2 / (top - bottom), 0, -((top + bottom) / (top - bottom)) },
new float[] { 0, 0, -2 / (zfar - znear), -((zfar + znear) / (zfar - znear)) },
new float[] { 0, 0, 0, 1 },
});
}
/* The static method used to return a perspective projection matrix */
public static Matrix4D perspective(float fov, float aspect, float zNear, float zFar) {
float f = (float) (1f / Math.tan(fov / 2f));
return new Matrix4D(new float[][] {
new float[] { f / aspect, 0, 0, 0 },
new float[] { 0, f, 0, 0 },
new float[] { 0, 0, (zFar + zNear) / (zFar - zNear), (2 * zFar * zNear) / (zNear - zFar) },
new float[] { 0, 0, -1, 0 },
});
}
}
最后,建立透视/正投影的方法是:
/* The static method to setup an orthographic view given the width, height
* znear and zfar values */
public static void setupOrtho(float width, float height, float znear , float zfar) {
Matrix.loadIdentity(Matrix.modelMatrix);
Matrix.loadIdentity(Matrix.viewMatrix);
Matrix.projectionMatrix = Matrix.ortho(0, width, 0, height, znear, zfar);
}
/* The static method used to setup a perspective view given the
* fov, z near and z far value */
public static void setupPerspective(float fov, float zNear, float zFar) {
setupPerspective(fov, (float) (Settings.Window.Width / Settings.Window.Height), zNear, zFar);
}
/* The static method used to setup a perspective view given the
* fov, aspect ratio, z near and z far values */
public static void setupPerspective(float fov, float aspect, float zNear, float zFar) {
Matrix.loadIdentity(Matrix.modelMatrix);
Matrix.loadIdentity(Matrix.viewMatrix);
Matrix.projectionMatrix = Matrix.perspective(fov, aspect, zNear, zFar);
}
渲染所有这些并将矩阵传递给我使用的着色器
//Multiply the matrices together
Matrix4D modelViewMatrix = Matrix.multiply(Matrix.modelMatrix, Matrix.viewMatrix);
Matrix.modelViewProjectionMatrix = (Matrix.multiply(modelViewMatrix, Matrix.projectionMatrix));
System.out.println(Matrix.modelViewProjectionMatrix.toString() + "\n");
在着色器中,我将当前顶点的位置与模型视图投影marix相乘。
你的矩阵相乘的顺序似乎不对。当组合矩阵变换时,方程右边的一个将是执行的第一个变换。
您将矩阵计算为模型×视图×投影。当将其乘以向量时,将首先执行投影,然后是视图转换,最后是模型转换。显然这不是你想要的。
你的最终矩阵应该像投影×视图×模型那样计算,以正确的顺序进行转换。
我有一个基本的OpenGL应用程序,我想使用我的投影矩阵。 这是我的矩阵: (WorldCoordinates是Matrix4结构,它只包含一个名为m的变量,即浮点[4][4])(宽度和高度是两个s)。然后,我使用以下方法将此坐标应用于我的<code>顶点 (Shader是一个类,并且有一个绑定()方法,它只是glUseProgram)。 这是我的顶点着色器GLSL 使用这个,它不起作用。但将gl
在使用numpy的python中,假设我有两个矩阵: 稀疏矩阵 密集的x*y矩阵 现在我想做,它将返回一个密集的矩阵。 但是,我只关心中非零的单元格,这意味着如果我这样做了,对我的应用程序不会有任何影响 <代码>S\u=S*S\u 显然,这将是对操作的浪费,因为我想把在
着色器语言中通过关键字mat2、mat3、mat4分别声明一个2x2矩阵、3x3矩阵、4x4矩阵,通过内置函数mat2()、mat3()、mat4()分别创建一个2x2矩阵、3x3矩阵、4x4矩阵。 关键字 数据类型 mat2 2x2矩阵,4个元素 mat3 3x3矩阵,9个元素 mat4 4x4矩阵,16个元素 声明变量 关键子mat4声明一个4x4矩阵 mat4 matrix4; 构造函数赋
注:我也在这里的Eigen论坛上发表了这篇文章 我想用一个3x3矩阵预乘3xN个矩阵,即,变换3D点,如p_dest=T*p_source 初始化矩阵后: 而且 进行NT重复只是为了计算平均时间 我很惊讶逐列乘法比直接乘法快4/5倍(如果我不使用,直接乘法甚至更慢,但这没有问题,因为它是临时复制)。我尝试将NUMCOLS从0改为1000000,关系是线性的。
我有一个看起来像这样的请求: http://localhost:8080/car/BMW;颜色=红色 返回汽车模型及其颜色作为 json 数据。如果我在没有指定颜色的情况下执行请求,它将默认为绿色。 Java代码: 当我将url复制/粘贴到浏览器时,它会按预期返回json,但当我尝试放心地获取它时,我收到404未找到错误。我尝试发送带有参数(“颜色”,颜色)的请求,但它只是忽略参数并返回默认jso
我在查看一些代码时发现了以下内容: 有什么区别呢?顺便说一句:我对矩阵很陌生