2011-07-11 13 views
8

Digamos que tengo un sprite. Su cuadro delimitador alineado con el eje (AABB) es fácil de encontrar ya que conozco el ancho y la altura. Digamos que lo gire 45 grados, no creo que el AABB sea lo suficientemente grande como para cubrirlo, así que necesito un nuevo AABB. ¿Cómo puedo calcular el rectángulo delimitador de un rectángulo girado? (dado un punto central, un ángulo, y su ancho y alto).AABB de sprite girado?

Tenga en cuenta que OpenGL realiza la rotación, por lo que no tengo acceso a la información de vértice.

Lo que estoy tratando de hacer es obtener AABB para que pueda realizar el descarte 2D para el renderizado.

¿Existe posiblemente una forma codiciosa de encontrar el AABB que satisfaga cualquier ángulo?

Gracias

+5

Para aquellos que no están familiarizados, ¿tal vez podría mencionar que AABB = "cuadro delimitador alineado por el eje"? –

Respuesta

29

enter image description here

+5

+1: una imagen vale más que mil palabras. –

+0

Si sigue esta ruta, recuerde la AABB original y el ángulo de rotación actual, ya que, de lo contrario, a medida que aplique más y más rotaciones, la caja corregida será cada vez más grande (lo que la hará menos útil). La otra idea en su publicación (encontrar una AABB que funcione para todos los ángulos) también es bastante fácil (ver mi respuesta). –

+1

tenga en cuenta que la AABB rotada no será un límite óptimo en general a menos que el sprite sea en sí mismo un rectángulo; quiero decir, su AABB será estrictamente un "cuadro delimitador" (es decir: se garantiza que está dentro) pero podría haber un AABB rotado más pequeño que se ajuste al sprite. (por ejemplo, si sprite no tiene puntos cerca de las esquinas de la AABB) – lurscher

0

No sé si este es el método más eficiente, pero me acaba de calcular las nuevas posiciones de los vértices y en base a los datos que averiguar la AABB. Por ejemplo,

Vertex v0, v1, v2, v3; 
// in the local coordinates of the rectangle 
// so for example v0 is always 0,0 and width and height define the others 
// put some values to v0..v3 

glLoadIdentity(); 
glTranslatef(the position of the rectangle); 
glTranslatef(center_point); 
glRotatef(angle, 0,0,1); 
glTranslatef(-center_point); 

GLfloat matrix[16]; 
glGetFloatv(GL_MODELVIEW_MATRIX, matrix); 

v0 = multiply_matrix_by_vector(matrix, v0); 
v1 = multiply_matrix_by_vector(matrix, v1); 
v2 = multiply_matrix_by_vector(matrix, v2); 
v3 = multiply_matrix_by_vector(matrix, v3); 

AABB = find_the_minimums_and_maximums(v0, v1, v2, v3); 

Si no sabe cómo multiplicar una matriz por vector, intente buscar en Google.

También tenga en cuenta que dado que las dimensiones de la matriz son 4x4, los vectores para los vértices también deben ser de 4 dimensiones. Puede convertir un vector 2D en un vector 4D agregando un tercer componente 0 (cero) y un cuarto componente 1 (uno). Después de que se haya realizado la multiplicación, puede convertir el vector 4D resultante en 2D dividiendo los componentes x e y por el cuarto componente y simplemente ignorando el tercer componente porque no necesita una tercera dimensión.

Dado que las multiplicaciones de matrices pueden ser una operación bastante pesada para el procesador, este enfoque podría ser bueno solamente, si no es necesario actualizar muchas AABB muy a menudo.

+1

OpenGL tiene 'glMultMatrix', así que es mejor que lo uses. –

+0

sí. excepto que glMultMatrix probablemente hace un trabajo extra porque multiplica matrices por matrices en lugar de matrices por vectores.pero eso probablemente sea correcto ya que este método probablemente sea lento de todos modos. – kynnysmatto

+0

Está multiplicando cuatro vectores por la misma matriz 4 × 4, por lo que podría hacerlos todos a la vez ... –

1

Si desea una sola caja que cubra todos los ángulos, simplemente tome la media diagonal de su caja existente como el radio de un círculo. La nueva caja debe contener este círculo, por lo que debe ser un cuadrado con una longitud lateral igual al doble del radio (equivalente a la diagonal de la AABB original) y con el mismo centro que el original.

En general, el objeto se rotará alrededor de un punto arbitrario, por lo que debe calcular la nueva ubicación del centro y traducir este cuadro al lugar correcto.

Cuestiones relacionadas