OpenGL the direction of translation is not right after rotation - opengl

I'm writing a simple demo with the fixed pipeline mode in OpenGL
First I write some codes that will draw a rectangle, with top-left point (x1,y1), and buttom-right point (x2,y2)
// Drawing here
glPushMatrix();
// Perform rotation first
glTranslatef(x_cent, y_cent, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(scale, scale, 1.0f);
// Set origin back to the screen center with the rotation set above
glTranslatef(-x_cent, -y_cent, 0.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
{
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glVertex2f(x1, y1);
}
glEnd();
// End of drawing
glPopMatrix();
After I tweak the value of the angle with arrow keys, say 45 degrees counter-clockwise, and now the rectangle will rotate 45 degrees counter-clockwise. Then I translate it with arrow keys, it moves in the direction of up, down, left, and right. Everything works fine.
So I write anoter part of code that will draw a general polygon. It's similar to the code above. I simply draw lines between each pair of points
for (int i = 0; i < p_size; i++)
{
float x1 = point[i].x, x2 = point[(i + 1) % p_size].x;
float y1 = point[i].y, y2 = point[(i + 1) % p_size].y;
x1 = ((x1 + 0.5f) / winWidth) * 2.0f - 1.0f;
x2 = ((x2 + 0.5f) / winWidth) * 2.0f - 1.0f;
y1 = ((-y1 + 0.5f) / winHeight) * 2.0f + 1.0f;
y2 = ((-y2 + 0.5f) / winHeight) * 2.0f + 1.0f;
// Set the curent coord origin to this poly's center
float x_cent = (left + right) / 2.0, y_cent = (top + down) / 2.0;
float ratio = winWidth / winHeight;
if (ratio > 1)
{
x1 *= ratio;
x2 *= ratio;
}
else //if (ratio < 1)
{
y1 /= ratio;
y2 /= ratio;
}
// Drawing here
glPushMatrix();
// Perform rotation first
glTranslatef(x_cent, y_cent, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(scale, scale, 1.0f);
// Set origin back to the screen center with the rotation set above
glTranslatef(-x_cent, -y_cent, 0.0f);
glBegin(GL_LINES);
{
glVertex2f(x1, y1);
glVertex2f(x2, y2);
}
glEnd();
// End of drawing
glPopMatrix();
}
I rotate the polygon with arrow keys, that works fine, say also 45 degrees counter-clockwise. But after the rotation, when I translate it with up key, it moves not up but in the direction of 45 degrees.
Bbut why can the rectangle translate normally in the 4 directions after rotation? These two part of codes are almost the same, why is this happening...

Related

OpenGL independent rotation

I'm trying to draw these shaped bellow this this:
What I want
Tried this code:
glLoadIdentity();
glColor3f(0.98f, 0.83f, 0.73f);
glBegin(GL_POLYGON);
for (float i = 0; i <= (2 * p); i += 0.001) {
x = 100 * cos(i)-10;
y = 115 * sin(i)+270;
glVertex2f(x, y);
}
glEnd();
glRotatef(-135.0f, 0.0f, 0.0f, 1.0f);
glColor3f(1.0f, 0.83f, 0.0f);
glBegin(GL_POLYGON);
for (float i = p; i <= (2 * p); i += 0.001) {
x = 100 * cos(i) - 10;
y = 115 * sin(i) + 270;
glVertex2f(x, y);
}
But this is what I get:
What I get
If I want to only use the glLoadIdentity and glRotatef for rotation, do you have any idea about how to fix it?
Note:
I don't want to use push/pop or translation
You have to rotate the object around its center and move the rotated object to its position in the world. glRotatef rotates the vertices around (0, 0). Draw the object around (0, 0) and glTranslate to move the object to its position in the world:
glTranslate(-10.0f, 270.0f, 0.0f);
glRotatef(-135.0f, 0.0f, 0.0f, 1.0f);
glColor3f(1.0f, 0.83f, 0.0f);
glBegin(GL_POLYGON);
for (float i = p; i <= (2 * p); i += 0.001) {
x = 100 * cos(i);
y = 115 * sin(i);
glVertex2f(x, y);
}
Note, the matrix operations like glRotate and glTranslate specify a new matrix and multiply the current matrix by the new matrix.
If you are not allowed to use glTranslate, you have to rotate the translation vector (-10, 270) in the opposite direction. Use the trigonometric functions sin an cos to rotate the vector (see Rotation matrix). You need to invert the angle and convert it to Radians since the unit of sin and cos is Radian.
float tx = -10.0f;
float ty = 270.0f;
float angle = -135.0f;
float inv_angle_rad = -angle * M_PI / 180.0f;
float tx_rot = tx * cos(inv_angle_rad) - ty * sin(inv_angle_rad);
float ty_rot = tx * sin(inv_angle_rad) + ty * cos(inv_angle_rad);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glColor3f(1.0f, 0.83f, 0.0f);
glBegin(GL_POLYGON);
for (float i = p; i <= (2 * p); i += 0.001) {
x = 100 * cos(i) + tx_rot;
y = 115 * sin(i) + ty_rot;
glVertex2f(x, y);
}

Draw and Rotate an Arrow

I am trying to draw an arrow using the style below but this arrow should be also rotated according to a condition (need to pass the degree for each condition). I can draw the rectangle and a triangle but I cannot draw the triangle as an arrowhead. Also, how can I include the rotation degree into the code? Is there any easier way to draw an arrow and rotate it?
int triangleRect=4, triangleTri=3, lineWidth=3;
double twicePi = 2.0f * M_PI, angle_offsetR =1.5* M_PI/2, radius = 0.05,
xR=m_start.x(), y=m_start.y(), xT=m_start.x()+ m_rect_width;
glColor3f(0,1,0);
glLineWidth(lineWidth);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_MULTISAMPLE);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glBegin(GL_TRIANGLE_FAN);
//RECTANGLE
for(int i = 0; i <= triangleRect; i++) {
glVertex2f((xR + (radius * cos(i * twicePi / triangleRect + angle_offsetR)))* m_parent_width_function(),
(y + (radius * sin(i * twicePi / triangleRect + angle_offsetR)))* m_parent_height_function());
}
// TRIANGLE
for(int i = 0; i <= triangleTri; i++) {
glVertex2f((xT + (radius * cos(i * twicePi / triangleTri + angle_offsetR)))* m_parent_width_function(),
(y + (radius * sin(i * twicePi / triangleTri + angle_offsetR)))* m_parent_height_function());
}
glEnd();
You accidentally add angle_offsetR to the angle for the triangle vectors. Furthermore you've to restart a GL_TRIANGLE_FAN primitiv when you draw an new shape (see Triangle primitives).
If you want to rotate the model, then set the add a rotation around the z axis to the model view matrix by glRotatef.
Do not translate and scale the vertex coordinates. Use glScale and glTranslate. The matrix transformations are not commutative, the order matters:
float angle_of_roation = 30.0; // 30°
glPushMatrix();
// scale
glScalef( m_parent_width_function(), m_parent_height_function(), 1.0f);
// move triangle and rectangle to the position in the world
glTranslatef(xR, y, 0.0f);
// roatate triangle and rectangle
glRotatef(angle_of_roation, 0, 0, 1);
//RECTANGLE
glBegin(GL_TRIANGLE_FAN);
for(int i = 0; i <= triangleRect; i++) {
float angle = i * twicePi / triangleRect + angle_offsetR;
glVertex2f(radius * cos(angle), radius * sin(angle));
}
glEnd();
glPushMatrix();
// translate triangle relative to rectangle
glTranslatef(xT-xR, 0.0f, 0.0f);
// TRIANGLE
glBegin(GL_TRIANGLE_FAN);
for(int i = 0; i <= triangleTri; i++) {
float angle = i * twicePi / triangleTri;
glVertex2f(radius * cos(angle), radius * sin(angle));
}
glEnd();
glPopMatrix();
glPopMatrix();

Rotation along a path in opengl

i want to move an object along a path (sine wave), lets suppose object is a roller coaster.
it moves through translate but my problem is that i also want to rotate that object according to the path.
i tried this code before translate but its not working.
if (x = -4.8)
{
glRotatef(89, 1, 1, 0);
}
my code with only translation looks like this.
i want to add rotation here along sine waves
void object()
{ glPushMatrix();
glTranslatef(x, y, 0);
glColor3f(0.0f, 0.0f, 0.0f);//Set drawing color
glBegin(GL_QUADS);
glVertex2f(-0.3, 0.1);
glVertex2f(0.3, 0.1);
glVertex2f(0.3, -0.1);
glVertex2f(-0.3, -0.1);
glEnd();
glFlush();
glPopMatrix();
glFlush();
}
void drawsine()
{
glBegin(GL_LINE_STRIP);//Primitive
glColor3f(255, 0, 0);//Set drawing color
int i = 0;
float x = 0, y = 0;
for (x = -5; x < 6; x = x + 0.1)
{
y = (sin(3.142*x)) / 3.142*x;
glVertex2f(x, y);
//int j= 0;
sinex[i] = x;
siney[i] = y;
i++;
}
glEnd();
glFlush();
}
The angle of rotation depends on the direction vector along the sine wave.
The direction vector can be calculated by the subtraction of 2 positions. Subtract the position before the current position from the positions after the current position, to calcaulte the direction vector. In the following i is the current position of the object:
dx = sinex[i+1] - sinex[i-1];
dy = siney[i+1] - siney[i-1];
The angle of rotation can be calculated by the arcus tangent using atan2, which returns an angle in radians:
float ang_rad = atan2( dy, dx );
Since the angle has to be passed to glRotatef in degrees, the angle has to be converted from radians to degrees, before a rotation around the z axis can be performed.
A full circle in has 360 degrees or 2*Pi radians. So the scale from radians to degrees 180/Pi:
float ang_deg = ang_rad * 180.0f / M_PI;
glRotatef( ang_deg, 0, 0, 1 );
The following cde snippet show how to apply the code. Be aware that there is no bounds check. This means i has to be grater or equal 1 and less than the number of points - 1 (1 <= i < 110):
#define _USE_MATH_DEFINES
#include <math.h>
{
// [...]
drawsine();
x = sinex[i];
y = siney[i];
dx = sinex[i+1] - sinex[i-1];
dy = siney[i+1] - siney[i-1];
object();
// [...]
}
void object()
{
glPushMatrix();
glTranslatef(x, y, 0);
float ang_rad = atan2( dy, dx );
float ang_deg = ang_rad * 180.0f / M_PI;
glRotatef( ang_deg, 0, 0, 1 );
glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(-0.3, 0.1);
glVertex2f(0.3, 0.1);
glVertex2f(0.3, -0.1);
glVertex2f(-0.3, -0.1);
glEnd();
glPopMatrix();
}

Open GL Rotation

i'm trying to draw 100 arrows in a grid and trying to rotate each arrow according to the size of the input i read. But here when i try to rotate one arrow, all the arrows rotate at once with it. whats wrong with it ?
void drawArrow(void) {
float y1 = 2.0;
float y2 = 2.15;
float y3 = 2.4;
int count2 = 0;
for (float col = 0; col < 10; col++) {
y1 -= 0.5;
y2 -= 0.5;
y3 -= 0.5;
float x1 = -2.25;
float x2 = -2.20;
float x3 = -2.15;
float x4 = -2.35;
float x5 = -2.30;
for (float rows = 0; rows < 10; rows++) {
glPushMatrix();
glTranslatef(-0.35 + 0.5 - 0.1, 0.4 - 0.01 + 0.1, 0.0);
float m = (windx[count2] * windx[count2]) + (windy[count2] * windy[count2]);
float rotator = sqrt(m);
glRotatef(rotator-50, 0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);//start drawing a line loop
glColor3f(1.0, 0.0, 0.0);
glVertex3f(x1, y1, 0.0f);
glVertex3f(x2, y2, 0.0f);
glVertex3f(x3, y2, 0.0f); // drawing a arrow
glVertex3f(x1, y3, 0.0f);
glVertex3f(x4, y2, 0.0f);
glVertex3f(x5, y2, 0.0f);
glVertex3f(x1, y1, 0.0f);
x1 += .5;
x2 += .5;
x3 += .5;
x4 += .5;
x5 += .5;
count2 ++;
glEnd();//end drawing of line loop
glPopMatrix();
}
}
int main(int argc, char **argv) {
glMatrixMode(GL_PROJECTION);
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_SINGLE); // Set up a basic display buffer (only single buffered for now)
glutInitWindowSize(1000, 800); // Set the width and height of the window
glutInitWindowPosition(100, 100); // Set the position of the window
glutCreateWindow("Weather Analysis"); // Set the title for the window
readDataFile(); //Read Data From File
glutKeyboardFunc(keyboard);
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
glutMainLoop(); // Enter GLUT's main loop
void reshape(int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}
void display(void) {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(0.0f, 0.5f, -6.0f);
renderPrimitive(); // Render the primitive
drawArrow();
glFlush(); // Flush
}
and ALSO i dont know what to enter in the GLtranslatef method. Im really a beginner, sorry.
Try to draw your arrow in one rutine lets call it DrawArrow I suggest it size must be between [-1.0f; 1.0f] than place it at the proper position using affine transform first of all translation secondly rotation.
void DrawArrow(void)
{
float x1 = 0;
float x2 = -0.05;
float x3 = -0.1;
float x4 = 0.1;
float x5 = 0.05;
float y1 = -0.15;
float y2 = 0;
float y3 = 0.15;
glBegin(GL_LINE_STRIP);//start drawing a line loop
glColor3f(1.0, 0.0, 0.0);
glVertex3f(x1, y1, 0.0f);
glVertex3f(x2, y2, 0.0f);
glVertex3f(x3, y2, 0.0f); // drawing a arrow
glVertex3f(x1, y3, 0.0f);
glVertex3f(x4, y2, 0.0f);
glVertex3f(x5, y2, 0.0f);
glVertex3f(x1, y1, 0.0f);
glEnd();//
}
Than your array drawing function like this (you may correct inacurrances):
void drawArrows(void) {
float y1 = 2.0;
int count2 = 0;
for (float col = 0; col < 10; col++) {
y1 -= 0.5;
float x1 = -2.25;
for (float rows = 0; rows < 10; rows++) {
glPushMatrix();
glTranslatef(x1, y1, 0.0);
float m = (windx[count2] * windx[count2]) + (windy[count2] * windy[count2]);
float rotator = sqrt(m);
glRotatef(rotator-50, 0.0, 0.0, 1.0);
DrawArrow();
x1 += .5;
count2 ++;
glPopMatrix();
}
}
}
I have made some tests the result will be like this (with constant rotator).

opengl: rotating an ellipse

I am having trouble rotating an ellipse in OpenGL. So, I have some code to draw an ellipse as follows:
glPushAttrib(GL_CURRENT_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glLineWidth(2.0);
glPushMatrix();
glTranslatef(0, 0, 0); // ellipse centre
glBegin(GL_LINE_LOOP);
float inc = (float) M_PI / 500.0;
for (GLfloat i = 0; i < M_PI * 2; i+=inc)
{
float x = cos(i) * 0.4;
float y = sin(i) * 0.4;
glVertex2f(x, y);
}
glEnd();
glPopMatrix();
glPopAttrib();
This produces a picture as so:
Now what I want to do is rotate this ellipse clockwise. So I added a glrotate in between but the result was not what I had expected.
So, I did something like:
glPushAttrib(GL_CURRENT_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glLineWidth(2.0);
glPushMatrix();
glTranslatef(0, 0, 0);
glRotatef(-90, 1, 1, 0);
glBegin(GL_LINE_LOOP);
float inc = (float) M_PI / 500.0;
for (GLfloat i = 0; i < M_PI * 2; i+=inc)
{
float x = cos(i) * 0.4;
float y = sin(i) * 0.4;
glVertex2f(x, y);
}
glEnd();
glPopMatrix();
glPopAttrib();
This produced an image which was simply collapsed. What I wanted to do was rotate the ellipse along its center by the specified degrees. Also, I tried playing around with the various parameters of glRotatef but could not get it do as I expected. The resulting image looks like:
You're working in the XY plane, so you can't really rotate around a vector in XY. Instead, you want to rotate along the unit Z axis (glRotate (angle, 0, 0, 1);). Imagine your screen being the XY coordinate system and the Z axis pointing inwards. What you want is to rotate around the Z axis, so your XY plane remains in the XY plane.