Sunday, October 26, 2014

How to implement basic transformations on objects


I have taught CGV under Visvesvaraya Technological University more than six times and you may ask did I not get bored? Yes I did. Three times in the 1998/2002 scheme and three times in the 2006/2010 scheme. There is a vast difference between the syllabus of the earlier scheme and that of the 2006 scheme and onwards. Earlier scheme relied on textbook by James D Foley and others. The 2006 scheme follows Edward Angel and has introduced OpenGL to computer science students.
Students of yesteryears including me learn’t the now obsolete graphics.h library. I still remember those says when I had purchased a computer and was hunting for the EGAVGA.BGI file from my computer assembler. Coming to the topic It might strike you late but the importance of mathematics in Computer Graphics and Visualization is as Breath is to Life.
I will take you on a journey into a bit of transformations and how to realize them. “Your geometry lessons in schools will help you learn to write Graphics Programs”. Yes you heard it right.

Translation

One of the first things that a student of computer graphics learns is to move an object from one place to another. Actually, We draw an object at a particular place. So all we need to do to move it is to erase the object from that place and draw it at a new place (position). Place/position is measured with respect to a co-ordinate system. It may be 2-D or 3D coordinate system with x,y and z axis. A point may have three values like this:
int p1x,p1y,p1z; // non object oriented way
or
class point // object oriented way
{
int x,y,z;
};
point p1;
Now comes the most interesting part…. In OpenGL, transformations are implemented as functions. So if you want to apply any transformation on an object calling the transformation function before drawing the object will be sufficient to apply that transformation on that object.
So we have a function called glTranslatef to translate an object from one place to another. This function changes the position where objects are drawn.
Look at this code:
glTranslatef(4.0,3.0,0);
drawtriangle();
It draws a triangle at current raster position. That position is moved by glTranslatef() function to 4 units right(x axis) and three units up(y axis).

Rotation

All students of CSE/MCA would want to implement rotation in their projects but would not know how to rotate a particular object in the scene. Suppose I have drawn a line on the screen like this:
glBegin(GL_LINES);
glVertex2f(p1x,p1y);
glVertex2f(p2x,p2y);
glEnd();
This piece of code is present somewhere in the display function or any other function which is called from within display.

I want to rotate this line with respect to its centre. How to I do that?

You would have studied in your course about glPushMatrix(); and glPopMatrix(); functions. There is something called as the current transformation matrix (CTM). All objects going through the pipeline undergo these transformations. So if you want to apply a transformation to only the object you selected you just need to save the current transformation matrix somewhere so that it can be retrieved later. No better place than the stack to save it. PushMatrix saves the CTM on the stack and PopMatrix pops it from the stack and makes it the CTM.

To rotate this line we need to write the following code:
glPushMatrix();
glTranslatef((p1x+p2x)/2,(p1y+p2y)/2)); // go to a position at the center of the line 
glRotatef(10,0,1,0); // Rotate by 10 degrees the line wrt y-axis(0,1,0)
glTranslatef(-(p1x+p2x)/2,-(p1y+p2y)/2)); // go to a position at the center of the line
glBegin(GL_LINES);
glVertex2f(p1x,p1y);
glVertex2f(p2x,p2y);
glEnd();
glPopMatrix();

This code will draw the line in a rotated position. If you want continuous rotation you will need to increment this angle ‘10’ continuously by substituting a variable in its place. Here is the entire program to draw a rotating line while another object(teapot) nearby is stationary.
This snapshot represents the output:

Scaling:

Similar to rotation you would want objects to become big and small. Scaling an object involves calling the function glScalef();
So it it’s a 3D object like a teapot then glutSolidTeapot() is used to draw a teapot. To draw a teapot of different size we would
….. // here you would move the raster position to where
….. // you want to draw the teapot
glPushMatrix();
glScalef(2,2,2);
glutSolidTeapot();
glPopMatrix();

Here is a program where there is a rotating line and a teapot drawn with varying sizes and another nearby object(line) is not scaled but slowly rotating.
 Snapshot:

I hope your problem of applying transformations to selected objects is solved now. Happy Coding.