2009-09-24 5 views
6

Hé les gars, je suis en train de calculer les sommets d'un rectangle en rotation (2D).Calcul des sommets d'un rectangle pivotée

Il est assez facile si le rectangle n'a pas été tourné, je me suis partie dehors.

Si le rectangle a été tourné, je pensais que deux façons de calculer les sommets. 1) Déterminez comment transformer les sommets de l'espace local/objet/modèle (ceux que j'ai compris ci-dessous) en espace monde. Honnêtement, je n'ai aucune idée, et si c'est le meilleur moyen alors je sens que j'apprendrais beaucoup de lui si je pouvais le comprendre ...

2) Utilisez trig pour comprendre d'une manière ou d'une autre où les extrémités de la Le rectangle est relatif à la position du rectangle dans l'espace du monde. C'est ce que j'ai essayé de faire jusqu'à présent, je n'ai pas compris comment.

est ici la fonction qui calcule les sommets jusqu'ici, merci pour toute l'aide

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); 

} 

Répondre

16

Je voudrais juste transformer chaque point, en appliquant la même matrice de rotation à chacun. Si elle est une rotation plane 2D, il se présente comme suit:

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

où (x, y) sont les points d'origine, (x 'y') sont les coordonnées ayant tourné, et t est l'angle mesuré en radians de l'axe des x. La rotation est dans le sens antihoraire comme écrit.

Ma recommandation serait de le faire sur papier une fois. Dessinez un rectangle, calculez les nouvelles coordonnées et redessinez le rectangle pour vous assurer qu'il est correct avant de coder. Utilisez ensuite cet exemple comme test unitaire pour vous assurer que vous l'avez correctement codé.

+1

+1 - J'ai tendance à préférer tourner le dos et ensuite faire un travail, rend la vie plus simple. –

+2

De cette façon, vous pouvez vous en tirer en effectuant seulement 2 opérations trig (si vous stockez les résultats de 'cos (t)' et 'sin (t)' avant de calculer les sommets tournés). – jnylen

+0

Comment cette formule pourrait-elle tourner dans le sens des aiguilles d'une montre? –

2

Je pense que vous étiez sur la bonne voie en utilisant atan() pour retourner un angle. Cependant, vous voulez passer height divisé par width au lieu de l'inverse. Cela vous donnera l'angle par défaut (non tourné) au sommet supérieur droit du rectangle. Vous devriez être en mesure de faire le reste comme ceci:

// 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. 

De toute évidence plus verbeux que nécessaire, par souci de clarté. Bien sûr, la solution de duffymo utilisant une matrice de transformation est probablement plus élégante et efficace :)

EDIT: Maintenant, mon code devrait fonctionner. J'ai changé (width/height) en (height/width) et utilisé un rayon constant du centre du rectangle pour calculer les sommets. code Python travail (tortue) à http://pastebin.com/f1c76308c

+0

DEG_TO_RAD est une macro que j'ai écrite. –

Questions connexes