Вращающийся куб, чтобы показать только одну сторону - PullRequest
1 голос
/ 17 октября 2011

У меня есть 3D-куб с opengl, который вращается случайным образом и иногда останавливается, показывая до 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;
}

Кто-нибудь когда-нибудь делал что-то подобное или могпомогите мне?

Большое спасибо!

1 Ответ

0 голосов
/ 17 октября 2011

Определите локальный вектор v, который представляет сторону, которую вы хотите видеть. Например, если вы хотите увидеть отрицательную ось X, тогда v должно быть <-1,0,0>.

Если текущее вращение вашего куба относительно мира является матрицей вращения M, то умножение M * v даст вам направление, с которым лицо обращено относительно мира. То, что вы хотите, это применить другую матрицу N, которая поворачивает грань, чтобы указывать на вас, что обычно будет положительной осью Z:

N*M*v = <0,0,1>

Вы хотите, чтобы N было поворотом на определенный угол вокруг определенной оси. Ось будет перекрестным произведением направления, на которое она смотрит, и направления, к которому вы хотите, чтобы она смотрела:

axis=cross(M*v,<0,0,1>)/abs(cross(M*v,<0,0,1>))

Синус и косинус угла могут быть определены

cos_angle=dot(M*v,<0,0,1>)
sin_angle=abs(cross(M*v,<0,0,1>))

Угол равен

atan2(sin_angle,cos_angle)

Ваша новая матрица вращения M 'будет просто

M' = N*M
...