旋转立方体以仅显示一侧
我有一个用 opengl 制作的 3D 立方体,它随机旋转,偶尔会停止显示最多 3 个侧面。我想让立方体落在其中一侧(x,-x,y,-y,z,-z)。到目前为止,我设法确定了立方体的顶部 - 要显示的顶部。 但是我无法操纵立方体“回落”的矩阵。
假设我可以看到立方体的 X、Y 和 Z 面,并且我想旋转立方体,以便我只能看到 X 面。据我所知,要实现此目的,我需要旋转立方体Y 轴和 Z 轴。
例如,我想在 y 轴和 z 轴上旋转以下矩阵:
[0]=0.90366703 [1]=-0.4241817 [2]=-0.058799066 [3]=0.0 [4]=-0.3704742 [5]=- 0.70550096[6]=-0.6041675 [7]=0.0 [8]=0.21479362 [9]=0.56774914 [10]=-0.7946859 [12]=0.0 [13]=0.0 [14]=0.0 [15]=1.0
这就是我试图定义的方式角度:
float[] camera_org = new float[3];
GL11 gl11 = (GL11) gl;
gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, mdl);
camera_org[0] = -(mdl.get(0) * mdl.get(12) + mdl.get(1) * mdl.get(13) + mdl.get(2) * mdl.get(14));
camera_org[1] = -(mdl.get(4) * mdl.get(12) + mdl.get(5) * mdl.get(13) + mdl.get(6) * mdl.get(14));
camera_org[2] = -(mdl.get(8) * mdl.get(12) + mdl.get(9) * mdl.get(13) + mdl.get(10) * mdl.get(14));
Log.i("CubeOrientation", camera_org[0] + " " + camera_org[1] + " " + camera_org[2]
+ " "+ 90 / 6 * camera_org[0] + "° " + 90 / 6 * camera_org[1] + "° " + 90 / 6 * camera_org[2] + "°");
float angle_x = camera_org[0] < 0 ? 90 / 6 * camera_org[0] : -90 / 6 * camera_org[0];
float angle_y = camera_org[1] < 0 ? 90 / 6 * camera_org[1] : -90 / 6 * camera_org[1];
float angle_z = camera_org[2] < 0 ? 90 / 6 * camera_org[2] : -90 / 6 * camera_org[2];
angle_x = angle_x < 0 ? angle_x + 90 : angle_x - 90;
angle_y = angle_y < 0 ? angle_y + 90 : angle_y - 90;
angle_z = angle_z < 0 ? angle_z + 90 : angle_z - 90;
这就是我尝试进行计算的方式:
float x1 = matrix[0];
float y1 = matrix[1];
float z1 = matrix[2];
float x2 = matrix[4];
float y2 = matrix[5];
float z2 = matrix[6];
float x3 = matrix[8];
float y3 = matrix[9];
float z3 = matrix[10];
float[] xz1 = rotateY(angle_y, x1, z1);
float[] xz2 = rotateY(angle_y, x2, z2);
float[] xz3 = rotateY(angle_y, x3, z3);
matrix[0] = xz1[0]; // x
x1 = xz1[0];
matrix[2] = xz1[1]; // z
matrix[4] = xz2[0]; // x
x2 = xz2[0];
matrix[6] = xz2[1]; // z
matrix[8] = xz3[0]; // x
x3 = xz3[0];
matrix[10] = xz3[1]; // z
float[] xy1 = rotateZ(angle_z, x1, y1);
float[] xy2 = rotateZ(angle_z, x2, y2);
float[] xy3 = rotateZ(angle_z, x3, y3);
matrix[0] = xy1[0]; // x
matrix[1] = xy1[1]; // y
matrix[4] = xy2[0]; // x
matrix[5] = xy2[1]; // y
matrix[8] = xy3[0]; // x
matrix[9] = xy3[1]; // y
这就是我尝试计算的方式轮换:
/**
* Rotate X.
*
* @param angle_x
* @param y
* @param z
* @return [0] = y, [1] = z
*/
private float[] rotateX(float angle_x, float y, float z)
{
float[] res = new float[2];
res[0] = (float) (y * Math.cos(angle_x) - z * Math.sin(angle_x));
res[1] = (float) (y * Math.sin(angle_x) + z * Math.cos(angle_x));
return res;
}
/**
* Rotate Y.
*
* @param angle_y
* @param x
* @param z
* @return [0] = x, [1] = z
*/
private float[] rotateY(float angle_y, float x, float z)
{
float[] res = new float[2];
res[0] = (float) (x * Math.cos(angle_y) + z * Math.sin(angle_y));
res[1] = (float) (-x * Math.sin(angle_y) + z * Math.cos(angle_y));
return res;
}
/**
* Rotate Z.
*
* @param angle_z
* @param x
* @param y
* @return [0] = x, [1] = y
*/
private float[] rotateZ(float angle_z, float x, float y)
{
float[] res = new float[2];
res[0] = (float) (x * Math.cos(angle_z) - y * Math.sin(angle_z));
res[1] = (float) (y * Math.cos(angle_z) + x * Math.sin(angle_z));
return res;
}
有人做过类似的事情或者可以帮助我吗?
多谢!
I have a 3D-cube made with opengl which rotates randomly and stopps occasionally showing up to 3 of its sides. I would like to have the cube falling onto one of the sides (x, -x, y, -y, z, -z). I managed it so far to identify the top side of the cube - the one to be shown.
However I'm not able to manipulate the matrix that the cube "falls back".
Let's say I can see side X, Y and Z of the cube and I'd like to rotate the cube so that I can only see the side X. As far as I understand, to achieve this, I need to rotate the cube around the Y and Z axis.
As example I'd like to rotate following matrix on the y and z axis:
[0]=0.90366703 [1]=-0.4241817 [2]=-0.058799066 [3]=0.0 [4]=-0.3704742 [5]=-0.70550096 [6]=-0.6041675 [7]=0.0 [8]=0.21479362 [9]=0.56774914 [10]=-0.7946859 [12]=0.0 [13]=0.0 [14]=0.0 [15]=1.0
This is how I'm trying to define the angle:
float[] camera_org = new float[3];
GL11 gl11 = (GL11) gl;
gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, mdl);
camera_org[0] = -(mdl.get(0) * mdl.get(12) + mdl.get(1) * mdl.get(13) + mdl.get(2) * mdl.get(14));
camera_org[1] = -(mdl.get(4) * mdl.get(12) + mdl.get(5) * mdl.get(13) + mdl.get(6) * mdl.get(14));
camera_org[2] = -(mdl.get(8) * mdl.get(12) + mdl.get(9) * mdl.get(13) + mdl.get(10) * mdl.get(14));
Log.i("CubeOrientation", camera_org[0] + " " + camera_org[1] + " " + camera_org[2]
+ " "+ 90 / 6 * camera_org[0] + "° " + 90 / 6 * camera_org[1] + "° " + 90 / 6 * camera_org[2] + "°");
float angle_x = camera_org[0] < 0 ? 90 / 6 * camera_org[0] : -90 / 6 * camera_org[0];
float angle_y = camera_org[1] < 0 ? 90 / 6 * camera_org[1] : -90 / 6 * camera_org[1];
float angle_z = camera_org[2] < 0 ? 90 / 6 * camera_org[2] : -90 / 6 * camera_org[2];
angle_x = angle_x < 0 ? angle_x + 90 : angle_x - 90;
angle_y = angle_y < 0 ? angle_y + 90 : angle_y - 90;
angle_z = angle_z < 0 ? angle_z + 90 : angle_z - 90;
This is how I'm trying to make the calculations:
float x1 = matrix[0];
float y1 = matrix[1];
float z1 = matrix[2];
float x2 = matrix[4];
float y2 = matrix[5];
float z2 = matrix[6];
float x3 = matrix[8];
float y3 = matrix[9];
float z3 = matrix[10];
float[] xz1 = rotateY(angle_y, x1, z1);
float[] xz2 = rotateY(angle_y, x2, z2);
float[] xz3 = rotateY(angle_y, x3, z3);
matrix[0] = xz1[0]; // x
x1 = xz1[0];
matrix[2] = xz1[1]; // z
matrix[4] = xz2[0]; // x
x2 = xz2[0];
matrix[6] = xz2[1]; // z
matrix[8] = xz3[0]; // x
x3 = xz3[0];
matrix[10] = xz3[1]; // z
float[] xy1 = rotateZ(angle_z, x1, y1);
float[] xy2 = rotateZ(angle_z, x2, y2);
float[] xy3 = rotateZ(angle_z, x3, y3);
matrix[0] = xy1[0]; // x
matrix[1] = xy1[1]; // y
matrix[4] = xy2[0]; // x
matrix[5] = xy2[1]; // y
matrix[8] = xy3[0]; // x
matrix[9] = xy3[1]; // y
And this is how I'm trying to calculate the rotations:
/**
* Rotate X.
*
* @param angle_x
* @param y
* @param z
* @return [0] = y, [1] = z
*/
private float[] rotateX(float angle_x, float y, float z)
{
float[] res = new float[2];
res[0] = (float) (y * Math.cos(angle_x) - z * Math.sin(angle_x));
res[1] = (float) (y * Math.sin(angle_x) + z * Math.cos(angle_x));
return res;
}
/**
* Rotate Y.
*
* @param angle_y
* @param x
* @param z
* @return [0] = x, [1] = z
*/
private float[] rotateY(float angle_y, float x, float z)
{
float[] res = new float[2];
res[0] = (float) (x * Math.cos(angle_y) + z * Math.sin(angle_y));
res[1] = (float) (-x * Math.sin(angle_y) + z * Math.cos(angle_y));
return res;
}
/**
* Rotate Z.
*
* @param angle_z
* @param x
* @param y
* @return [0] = x, [1] = y
*/
private float[] rotateZ(float angle_z, float x, float y)
{
float[] res = new float[2];
res[0] = (float) (x * Math.cos(angle_z) - y * Math.sin(angle_z));
res[1] = (float) (y * Math.cos(angle_z) + x * Math.sin(angle_z));
return res;
}
Has anyone done something similar sometime or could help me out?
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
定义代表您想要看到的一侧的局部向量 v。例如,如果您想查看负 X 轴,则 v 应该为 <-1,0,0>。
如果立方体相对于世界的当前旋转是旋转矩阵 M,那么乘以 M*v 将得到面相对于世界的方向。您想要的是应用另一个矩阵 N 来旋转面以指向您,这通常是正 Z 轴:
您希望 N 是围绕特定轴的特定角度的旋转。轴将是它所面对的方向和您希望它面对的方向的叉积:
可以确定角度的正弦和余弦
角度是 那么
您的新旋转矩阵 M' 就是简单的
Define the local vector v that represents the side that you want to see. For example, if you want to see the negative X axis, then v should be <-1,0,0>.
If the current rotation of your cube relative to the world is the rotation matrix M, then multiplying M*v will give you the direction that the face is facing relative to the world. What you want is to apply another matrix N that rotates the face to point toward you, which would typically be the positive Z axis:
You want N to be a rotation of a particular angle about a particular axis. The axis will be the cross product of the direction it is facing and the direction you want it to face:
The sine and cosine of the angle can be determined
Angle is then
Your new rotation matrix M' is then simply