Java 透视图的单元测试
我已经在Java中进行了复制,但是当我将结果矩阵应用于向量时,输出z永远不会超过0.5(除了一点点浮点错误)。但是,它应该介于0(-z=zNear)和1(-z=zFar)之间 是否有针对该函数的单元测试,以便我可以测试我的实现是否匹配特定输入的已知正确输出?或者这个问题是基于一个错误的假设,z在0到0.5之间可以吗 或者,你能发现错误吗Java 透视图的单元测试,java,opengl,glu,Java,Opengl,Glu,我已经在Java中进行了复制,但是当我将结果矩阵应用于向量时,输出z永远不会超过0.5(除了一点点浮点错误)。但是,它应该介于0(-z=zNear)和1(-z=zFar)之间 是否有针对该函数的单元测试,以便我可以测试我的实现是否匹配特定输入的已知正确输出?或者这个问题是基于一个错误的假设,z在0到0.5之间可以吗 或者,你能发现错误吗 /** * @param fov the vertical viewing angle. This is the angle, in degrees, fro
/**
* @param fov the vertical viewing angle. This is the angle, in degrees, from the top of the screen to the bottom.
* @param aspect The aspect ratio, which controls the horizontal viewing angle relative to the vertical. We could imagine a variable fovx = aspect × fovy. For a non-stretched perspective, aspect should be the ratio of the screen width to height. For example, on a 640×480 display, aspect should be 4/3.
* @param near The inverted z coordinate of the near clipping plane.
* @param far The inverted z coordinate of the far clipping plane.
*/
public static Matrix4d create(double fov, double aspect, double near, double far) {
Preconditions.checkArgument(near > 0);
Preconditions.checkArgument(far > 0);
Preconditions.checkArgument(far < Double.POSITIVE_INFINITY);
double top = near * Math.tan(fov * Math.PI / 360.0);
double right = top * aspect;
double left = -right;
double bottom = -top;
return Matrix4d.create(
(2.0 * near) / (right - left), 0, 0, 0,
0, (2.0 * near) / (top - bottom), 0, 0,
(right + left) / (right - left), (top + bottom) / (top - bottom), (-far - near) / (far - near), -1.0,
0, 0, (-(2.0 * near) * far) / (far - near), 0
);
}
您是否可以显示实际“将矩阵应用于向量”的代码?您应该知道,要使透视深度范围正常工作,需要将向量的XYZ分量除以W post-projection.@AndonM.Coleman。如您所见,将执行按
w
除法。
public Vector3d multiplied(Vector3d other) {
final double r[] = new double[4]; // x, y, z, w
for (int lRow = 0; lRow < 4; lRow++) {
// calculate the dot product of the left row and the right vector
double dp =
(this.get(0, lRow) * other.x) +
(this.get(1, lRow) * other.y) +
(this.get(2, lRow) * other.z) +
(this.get(3, lRow) * 1);
r[lRow] = dp;
}
final double w = r[3];
if (w != 1) {
for (int i = 0; i < 3; i++) {
r[i] = r[i] / w;
}
}
return new Vector3d(r[0], r[1], r[2]);
}
fov 90, aspect 1.7777777777777777, near 1, far 1000
perspective:
0.5625000000000001, 0.0, 0.0, 0.0
0.0, 1.0000000000000002, 0.0, 0.0
0.0, 0.0, -1.002002002002002, -1.0
0.0, 0.0, -2.002002002002002, 0.0
IN OUT
outside clipping area
[0.0, 0.0, 0.0] [NaN, NaN, -Infinity]
[0.0, 0.0, -0.5] [0.0, 0.0, -0.4985]
[0.0, 0.0, -2000.0] [0.0, 0.0, 0.5002502499999999]
on clipping edges
[0.0, 0.0, -1.0] [0.0, 0.0, 9.999999999999775E-4]
[0.0, 0.0, -1000.0] [0.0, 0.0, 0.5000005]
centered
[0.0, 0.0, -2.0] [0.0, 0.0, 0.25075]
[0.0, 0.0, -4.0] [0.0, 0.0, 0.37562499999999993]
[0.0, 0.0, -20.0] [0.0, 0.0, 0.475525]
[0.0, 0.0, -40.0] [0.0, 0.0, 0.4880125]
[0.0, 0.0, -80.0] [0.0, 0.0, 0.49425625]
to the right
[100.0, 0.0, -20.0] [1.4048437500000004, 0.0, 0.475525]
[100.0, 0.0, -40.0] [0.7024218750000002, 0.0, 0.4880125]
to the left
[-100.0, 0.0, -20.0] [-1.4048437500000004, 0.0, 0.475525]
[-100.0, 0.0, -40.0] [-0.7024218750000002, 0.0, 0.4880125]
1 to the top
[0.0, -10.0, -10.0] [0.0, -0.4995000000000001, 0.45055]