Domanda

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

E 'abbastanza facile se il rettangolo non è stato ruotato, ho pensato che una parte fuori.

Se il rettangolo è stato ruotato, ho pensato a due possibili modi per calcolare i vertici. 1) Capire come trasformare i vertici da / oggetto / spazio modello locale (quelli che ho capito di seguito) allo spazio mondo. Onestamente ho idea, e se è il modo migliore, allora mi sento come avrei imparato molto da esso se potevo capirlo ...

2) Utilizzare trig per capire in qualche modo dove i punti finali del rettangolo sono relativi alla posizione del rettangolo nello spazio mondo. Questo è stato il modo in cui ho cercato di fare fino ad ora, io non ho 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);

}
È stato utile?

Soluzione

Vorrei solo 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 dal asse x. La rotazione è in senso antiorario come scritto.

Il mio consiglio sarebbe quello di farlo su carta una sola volta. Disegnare un rettangolo, calcolare le nuove coordinate, e ridisegnare il rettangolo di soddisfare te stesso che è corretto prima di codice. Quindi utilizzare questo esempio come una prova di unità per garantire che si codificati in modo corretto.

Altri suggerimenti

Credo che eri sulla strada giusta usando atan() di restituire un angolo. Tuttavia si desidera passare height diviso per width anziché il contrario. Che vi darà l'angolo di default (non ruotata) al 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ù longwinded del necessario, per motivi di chiarezza. Naturalmente, la soluzione di duffymo utilizzando una matrice di trasformazione è probabilmente più elegante ed efficiente:)

Modifica : Ora il mio codice dovrebbe effettivamente funzionare. Ho cambiato (width / height) a (height / width) e usato un raggio costante dal centro del rettangolo per calcolare i vertici. Working Python (tartaruga) il codice a http://pastebin.com/f1c76308c

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top