2009-09-24 26 views
6

Hola chicos, estoy tratando de calcular los vértices de un rectángulo girado (2D).Cálculo de vértices de un rectángulo girado

Es bastante fácil si el rectángulo no se ha girado, pensé que la parte fuera.

Si el rectángulo se ha girado, pensé en dos formas posibles de calcular los vértices. 1) Descubre cómo transformar los vértices del espacio local/objeto/modelo (los que descubrí a continuación) al espacio mundial. Honestamente, no tengo ni idea, y si es la mejor manera, entonces creo que aprendería mucho de ella si pudiera resolverlo ...

2) Utilice trig para averiguar de alguna manera dónde están los puntos finales de la rectángulo son relativos a la posición del rectángulo en el espacio mundial. Esta ha sido la forma en que he tratado de hacerlo hasta ahora, simplemente no he descubierto cómo.

Aquí está la función que calcula los vértices hasta ahora, gracias por cualquier ayuda

void Rect::calculateVertices() 
{ 
    if(m_orientation == 0) // if no rotation 
    { 
     setVertices(
     &Vertex((m_position.x - (m_width/2) * m_scaleX), (m_position.y + (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x + (m_width/2) * m_scaleX), (m_position.y + (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x + (m_width/2) * m_scaleX), (m_position.y - (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x - (m_width/2) * m_scaleX), (m_position.y - (m_height/2) * m_scaleY), m_position.z)); 
    } 
    else 
    { 
     // if the rectangle has been rotated.. 
    } 

    //GLfloat theta = RAD_TO_DEG(atan(((m_width/2) * m_scaleX)/((m_height/2) * m_scaleY))); 
    //LOG->writeLn(&theta); 

} 

Respuesta

16

me acaba de transformar cada punto, la aplicación de la misma matriz de rotación a cada uno. Si se trata de una rotación plana en 2D, que se vería así:

x' = x*cos(t) - y*sin(t) 
y' = x*sin(t) + y*cos(t) 

donde (x, y) son los puntos originales, (x 'y') son las coordenadas giradas, y t es el ángulo medido en radianes del eje x. La rotación es en sentido antihorario como está escrito.

Mi recomendación sería hacerlo una vez en papel. Dibuja un rectángulo, calcula las nuevas coordenadas y redibuja el rectángulo para asegurarte de que es correcto antes de codificar. Luego use este ejemplo como una prueba de unidad para asegurarse de que lo haya codificado correctamente.

+1

+1 - Tiendo a preferir girar hacia atrás y luego hacer cualquier trabajo, hace la vida más simple. –

+2

De esta manera puede salir adelante haciendo solo 2 operaciones trigonométricas (si almacena los resultados de 'cos (t)' y 'sin (t)' antes de calcular cualquier vértice girado). – jnylen

+0

¿Cómo sería rotar esta fórmula en el sentido de las agujas del reloj? –

2

Creo que estaba en el camino correcto usando atan() para devolver un ángulo. Sin embargo, desea pasar height dividido por width en lugar de al revés. Eso le dará el ángulo predeterminado (no girado) al vértice superior derecho del rectángulo. Usted debe ser capaz de hacer el resto de esta manera:

// Get the original/default vertex angles 
GLfloat vertex1_theta = RAD_TO_DEG(atan(
      (m_height/2 * m_scaleY) 
      /(m_width/2 * m_scaleX))); 
GLfloat vertex2_theta = -vertex1_theta; // lower right vertex 
GLfloat vertex3_theta = vertex1_theta - 180; // lower left vertex 
GLfloat vertex4_theta = 180 - vertex1_theta; // upper left vertex 

// Now get the rotated vertex angles 
vertex1_theta += rotation_angle; 
vertex2_theta += rotation_angle; 
vertex3_theta += rotation_angle; 
vertex4_theta += rotation_angle; 

//Calculate the distance from the center (same for each vertex) 
GLfloat r = sqrt(pow(m_width/2*m_scaleX, 2) + pow(m_height/2*m_scaleY, 2)); 

/* Calculate each vertex (I'm not familiar with OpenGL, DEG_TO_RAD 
* might be a constant instead of a macro) 
*/ 
vertexN_x = m_position.x + cos(DEG_TO_RAD(vertexN_theta)) * r; 
vertexN_y = m_position.y + sin(DEG_TO_RAD(vertexN_theta)) * r; 

// Now you would draw the rectangle, proceeding from vertex1 to vertex4. 

Obviamente más prolijo de lo necesario, en aras de la claridad. Por supuesto, la solución de Duffymo usando una matriz de transformación es probablemente más elegante y eficiente :)

EDIT: Ahora mi código debería funcionar. Cambié (width/height) a (height/width) y usé un radio constante desde el centro del rectángulo para calcular los vértices. Código de trabajo de Python (tortuga) en http://pastebin.com/f1c76308c

+0

DEG_TO_RAD es una macro que escribí. –

Cuestiones relacionadas