Girar triángulo en OpenGL

I'm trying to rotate a triangle around it's center point. I'm aware that OpenGL rotates about the origin so I need to translate the middle point to the origin, then rotate, and translate back. I've commented out this last line to ensure that it at least rotates about its center at the origin. It does not. It appears to be rotating about its old origin despite the translation... Note that ccc4 and ccp generate floats. Here's my code:

ccColor4B colors[] = {
    ccc4(255, 0, 0, 255),
    ccc4(0, 255, 0, 255),
    ccc4(0, 0, 255, 255)
};

CGPoint vertices[] = {
    ccp(0,0),
    ccp(50,100),
    ccp(100,0),
};

CGPoint middle[] = {ccp(50,50)};
CGPoint origin[] = {ccp(0,0)};

// Rotate the triangle
glPushMatrix();
glTranslatef(-50, -50, 0);
glRotatef(45, 0, 0, 1.0);
// glTranslatef(50, 50, 0);

// Draw the triangle
glLineWidth(2);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
glColor4ub(0, 0, 255, 255);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);

// Revert rotation, we only want triangle to rotate 
glPopMatrix();

// Draw the points
glDisableClientState(GL_COLOR_ARRAY);

glPointSize(5);
glColor4ub(255, 255, 255, 255);
glVertexPointer(2, GL_FLOAT, 0, middle);
glDrawArrays(GL_POINTS, 0, 1);

glPointSize(5);
glColor4ub(0, 255, 0, 255);
glVertexPointer(2, GL_FLOAT, 0, origin);
glDrawArrays(GL_POINTS, 0, 1);

glEnableClientState(GL_COLOR_ARRAY);
// End points

Aquí está el resultado:

1 2

preguntado el 02 de febrero de 12 a las 10:02

My triangle isn't even equilateral now that I noticed. I keep geting sqrt(3)/6 for the center point of an equilateral though... -

Would you happen to have a link to the proof? -

@AramKocharyan: Sorry, I gave you a bum-steer. That's the height of the triangle, not the center. The center which is just 1/3 in the y-axis, as per Vyktor's comment. -

1 Respuestas

You need to think of transforms as applying in reverse relative to the order in which you call them.

Actually, it's easier to think in terms of transforming the local coordinate system (LCS), not the object, which allows you to mentally apply transforms in the order they're called. To rotate about the center, translate the LCS to the center, rotate, then translate it back out again:

glTranslatef(50, 50, 0);
glRotatef(45, 0, 0, 1);
glTranslatef(-50, -50, 0);

Respondido 02 Feb 12, 15:02

Cheers! I'll remember to think in that mindset. It makes sense now. Drawing wrt the LCS means later draws are also wrt this LCS. - Aram Kocharyan

@AramKocharyan: That's correct. It also means that later transformadas are wrt the LCS. For instance, imagine you start with the identity transform, then call glScale(20, 20, 20) seguido por glRotate(45, 0, 0, 1). Si luego llamas glTranslate(1, 0, 0), the LCS will move 20 units diagonally up and to the right relative to the world. - Marcelo Cantos

Thanks Marcelo example that makes sense too. - Aram Kocharyan

Would you happen to know why scaling then rotating gives different results from rotating then scaling? - Aram Kocharyan

@AramKocharyan: Unless you are doing another transform in between, or the scaling factors are different for each axis, it shouldn't make any difference. Multiplying by a scale matrix with identical scale factors for each dimension is equivalent to multiplying by a scalar, which is commutative (i.e., glScale(f, f, f) can appear anywhere in a chain of transforms). - Marcelo Cantos

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.