2009-09-24 16 views
6

Ehi ragazzi, sto cercando di calcolare i vertici di un rettangolo ruotato (2D).Calcolo dei vertici di un rettangolo ruotato

È abbastanza facile se il rettangolo non è stato ruotato, ho capito quella parte.

Se il rettangolo è stato ruotato, ho pensato a due possibili modi per calcolare i vertici. 1) Scopri come trasformare i vertici dallo spazio locale/oggetto/modello (quelli che ho scoperto in basso) allo spazio mondiale. Onestamente non ne ho idea, e se è il modo migliore allora mi piacerebbe imparare molto da esso se potessi capirlo ...

2) Utilizzare trig per capire in qualche modo dove i punti finali del il rettangolo è relativo alla posizione del rettangolo nello spazio del mondo. Questo è stato il modo in cui ho cercato di fare fino ad ora, non ho ancora capito come.

Ecco la funzione che calcola i vertici finora, grazie per qualsiasi aiuto

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

} 

risposta

16

avrei appena trasformare ogni punto, applicando la stessa matrice di rotazione a ciascuno. Se si tratta di una rotazione planare 2D, sarebbe simile a questa:

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

dove (x, y) sono i punti originali, (x 'y') sono le coordinate ruotate, e t è l'angolo misurato in radianti dall'asse x. La rotazione è antioraria come scritto.

La mia raccomandazione sarebbe di farlo su carta una volta. Disegna un rettangolo, calcola le nuove coordinate e ridisegna il rettangolo per verificare che sia corretto prima di codificare. Quindi usa questo esempio come test unitario per assicurarti di averlo codificato correttamente.

+1

+1 - Io preferisco tornare indietro e quindi fare qualsiasi lavoro, semplifica la vita. –

+2

In questo modo è possibile ottenere solo con 2 operazioni trigonometriche (se si memorizzano i risultati di 'cos (t)' e 'sin (t)' prima di calcolare qualsiasi vertice ruotato). – jnylen

+0

Come si dovrebbe ruotare questa formula in senso orario? –

2

Penso che tu fossi sulla strada giusta utilizzando atan() per restituire un angolo. Tuttavia, si desidera passare height diviso per width anziché viceversa. Questo ti darà l'angolo di default (non ruotato) sul vertice in alto a destra del rettangolo. Si dovrebbe essere in grado di fare il resto in questo modo:

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

ovviamente più prolisso del necessario, per motivi di chiarezza. Naturalmente, la soluzione di duffymo utilizzando una matrice di trasformazione è probabilmente più elegante ed efficiente :)

EDIT: Ora il mio codice dovrebbe funzionare. Ho modificato (width/height) in (height/width) e ho utilizzato un raggio costante dal centro del rettangolo per calcolare i vertici. Codice di lavoro Python (tartaruga) http://pastebin.com/f1c76308c

+0

DEG_TO_RAD è una macro che ho scritto. –