Sobre rotación de las bolas luego de un choque

Sobre rotación de las bolas luego de un choque

de Jose Pedro Aguerre -
Número de respuestas: 0

Hola,

Distintos grupos han preguntado cómo manejar las rotaciones de una bola luego de que esta choque contra las paredes o contra otras bolas. Básicamente se puede hacer de dos formas:

1) una opción sencilla pero computacionalmente más costosa es guardar una lista de rotaciones por cada bola, donde se guarda el vector de rotación y el ángulo de rotación. En cada choque se agrega una nueva entrada a la lista con el vector correspondiente. Al renderizar la bola, es necesario recorrer la lista aplicando todas las rotaciones que haya tenido desde el comienzo de la partida.

2) otra opción más compleja pero computacionalmente eficiente es utilizando una matriz de rotación externa en lugar de glRotate. Cada bola tendrá su propia matriz de 4x4 que corresponda a su rotación global (combinación de todas las rotaciones hasta el momento). Para armar esa matriz pueden utilizar el código que les dejo abajo. Luego, en lugar de utilizar glRotate, deben utilizar la función glMultMatrixf para multiplicar su matriz de rotación por la matriz modelo actual.


Saludos,

José 


PD: para la opción 2 les paso un código para armar su propia matriz de rotación a partir de un ángulo y un eje (prueben el código porque no lo compilé):

Matrix  manualRotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

{

   GLfloat sinAngle, cosAngle;

   GLfloat mag = sqrtf(x * x + y * y + z * z);

      

   sinAngle = sinf ( angle * PI / 180.0f );

   cosAngle = cosf ( angle * PI / 180.0f );

   if ( mag > 0.0f )

   {

      GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;

      GLfloat oneMinusCos;

      Matrix rotMat;

   

      x /= mag;

      y /= mag;

      z /= mag;


      xx = x * x;

      yy = y * y;

      zz = z * z;

      xy = x * y;

      yz = y * z;

      zx = z * x;

      xs = x * sinAngle;

      ys = y * sinAngle;

      zs = z * sinAngle;

      oneMinusCos = 1.0f - cosAngle;


      rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;

      rotMat.m[0][1] = (oneMinusCos * xy) - zs;

      rotMat.m[0][2] = (oneMinusCos * zx) + ys;

      rotMat.m[0][3] = 0.0F; 


      rotMat.m[1][0] = (oneMinusCos * xy) + zs;

      rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;

      rotMat.m[1][2] = (oneMinusCos * yz) - xs;

      rotMat.m[1][3] = 0.0F;


      rotMat.m[2][0] = (oneMinusCos * zx) - ys;

      rotMat.m[2][1] = (oneMinusCos * yz) + xs;

      rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;

      rotMat.m[2][3] = 0.0F; 


      rotMat.m[3][0] = 0.0F;

      rotMat.m[3][1] = 0.0F;

      rotMat.m[3][2] = 0.0F;

      rotMat.m[3][3] = 1.0F;

   }

}