Friday, February 04, 2011

2D Transformation



/*
 * THIS PROGRAM DRAWS A TRIANGLE AND APPLY THE FOLLOWING SEQUENCES OF TRANSFORMATION ON
   A TRIANGLE AND SHOWS THE INTERMEDIATE TRANSFORMED FIGURES –
(A)  REFLECT THE OBJECT AROUND LINE y = mx + c
(B)   ROTATE BY 60 DEGREES KEEPING TOP MOST VERTEX FIXED
(C)  TRANSLATE ALONG X-AXIS BY 40 UNITS
(D)   ROTATE BY 180 DEGREES KEEPING TOP MOST VERTEX FIXED
(E)    SCALE BY SX=2 AND SY=0.5 ABOUT THE CENTROID OF THE OBJECT
 */
 
 #include<stdio.h>
 #include<stdlib.h>
 #include<conio.h>
 #include<graphics.h>
 #include<dos.h>
 #include<math.h>
  
 void drawFigure(float[][3]);
 void matrix_mult(float[][3],float[][3],float[][3]);
 void display(float[][3]);

 int unitx = 20,unity = 20;

 /*Function to create a grid so as to illustrate plotting of pixels*/
 void createGraph(){

            int midx,midy,x,y;

            midx = getmaxx()/2;   //the origin
            midy = getmaxy()/2;
            cleardevice();
            setbkcolor(WHITE);

            setcolor(BROWN);
            setlinestyle(SOLID_LINE,1,1);
            for(x=unitx;x<=getmaxx();x=x+unitx)
                        line(x,unity,x,getmaxy()-unity);
            for(y=unity;y<=getmaxy();y=y+unity)
                        line(unitx,y,getmaxx()-unitx,y);

            setcolor(RED);
            setlinestyle(SOLID_LINE,1,2);

            // draw the axes lines
            line(midx,0,midx,getmaxy());
            line(0,midy,getmaxx(),midy);
   }

 void main(){

            int gdriver=DETECT,gmode,ecode;
            float f[3][3];
            printf("\nEnter the 3 pairs of coordinates: ");
            scanf("%f%f%f%f%f%f",&f[0][0],&f[0][1],&f[1][0],&f[1][1],&f[2][0],&f[2][1]);

            f[0][2]=f[1][2]=f[2][2] = 1;

            float temp1[3][3],temp2[3][3],temp[3][3];

            int ox,oy;
            ox = getmaxx()/2;
            oy = getmaxy()/2;

            initgraph(&gdriver,&gmode,"C:\\TC\\bgi");
            ecode = graphresult();
            if (ecode != grOk){  /* an error occurred */
                        printf("Graphics error: %s\n", grapherrormsg(ecode));
                        printf("Press any key to halt:");
                        getch();
                        exit(1); /* terminate with an error code */
            }
            setbkcolor(WHITE);

            //(a) Reflect about line y=mx+c
            float c,m;
            double theta;
            printf("\nEnter the values of 'm' & 'c': ");
            scanf("%f%f",&m,&c);

            float y1,y2;
            y1 = m*(-10)+c;
            y2 = m*10+c;
           
            //finalT = [translate][rotate][reflect][rotate]'[translate]'
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=0; temp1[2][1]=-c; temp1[2][2]=1;
           
            theta = atan(m);         //get slope angle of the st. line

            temp2[0][0]=cos(theta);temp2[0][1]=-sin(theta);temp2[0][2]=0;
            temp2[1][0]=sin(theta);temp2[1][1]=cos(theta);temp2[1][2]=0;
            temp2[2][0]=0;temp2[2][1]=0;temp2[2][2]=1;
           
            matrix_mult(temp1,temp2,temp);      //translate & rotate
           
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=-1;temp1[1][2]=0;
            temp1[2][0]=0; temp1[2][1]=0; temp1[2][2]=1;

            matrix_mult(temp,temp1,temp2);      //reflect
           
            temp1[0][0]=cos(theta);temp1[0][1]=sin(theta);temp1[0][2]=0;
            temp1[1][0]=-sin(theta);temp1[1][1]=cos(theta);temp1[1][2]=0;
            temp1[2][0]=0;temp1[2][1]=0;temp1[2][2]=1;

            matrix_mult(temp2,temp1,temp);      //inverse rotate
           
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=0; temp1[2][1]=c; temp1[2][2]=1;

            matrix_mult(temp,temp1,temp2);      //translate back
           
            matrix_mult(f,temp2,temp);    //apply the transformation
           
            clrscr();
            createGraph();
            setbkcolor(WHITE);
            drawFigure(f);
            delay(1000);
            line(ox-10*unitx,oy+3*unity,ox+10*unitx,oy-7*unity);
            delay(1000);
            drawFigure(temp);      //draw the transformed figure

            delay(2000);
            cleardevice();
            closegraph();

            //(b) Rotate through 60 degree, about top vertex
            initgraph(&gdriver,&gmode,"C:\TC\bgi");
            ecode = graphresult();
            if (ecode != grOk){  /* an error occurred */
                        printf("Graphics error: %s\n", grapherrormsg(ecode));
                        printf("Press any key to halt:");
                        getch();
                        exit(1); /* terminate with an error code */
            }
            int d;
            float maxy,x;

            printf("\nClockwise '1'\nCounter-clockwise '2' ? ");
            scanf("%d",&d);

            if(d==2) d=-1;

            //determine the top most vertex
            maxy = f[0][1]; x = f[0][0];
            if(f[1][1]>maxy){
             maxy = f[1][1]; x = f[1][0]; }
            if(f[2][1]>maxy){
             maxy = f[2][1]; x = f[2][0]; }

            //finalT = [translate][rotate][translate]'
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=-x; temp1[2][1]=-maxy; temp1[2][2]=1;
           
            temp2[0][0]=cos(M_PI/3);temp2[0][1]=-d*sin(M_PI/3);temp2[0][2]=0;
            temp2[1][0]=d*sin(M_PI/3);temp2[1][1]=cos(M_PI/3);temp2[1][2]=0;
            temp2[2][0]=0;temp2[2][1]=0;temp2[2][2]=1;
           
            matrix_mult(temp1,temp2,temp);      //translate & rotate

            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=x;temp1[2][1]=maxy;temp1[2][2]=1;

            matrix_mult(temp,temp1,temp2);      //translate back

            matrix_mult(f,temp2,temp);    //apply transformation
           
            createGraph();
            drawFigure(f);
            delay(1000);
            drawFigure(temp);
            delay(2000);
            cleardevice();

            //(c) translate along x-axis by tx=8
            float tx=8;

            //finalT = [transalte]
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=tx;temp1[2][1]=0;temp1[2][2]=1;
           
            matrix_mult(f,temp1,temp);    //apply transformation

            createGraph();

            drawFigure(f);
            delay(1000);
            drawFigure(temp);
            delay(2000);
            cleardevice();
           
            //(d) rotate by 180 degree keeping top most vertex fixed
           
            //determine the top most vertex
            maxy = f[0][1]; x = f[0][0];
            if(f[1][1]>maxy){
             maxy = f[1][1]; x = f[1][0]; }
            if(f[2][1]>maxy){
             maxy = f[2][1]; x = f[2][0]; }

            //finalT = [translate][rotate][translate]'
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=-x; temp1[2][1]=-maxy; temp1[2][2]=1;

            temp2[0][0]=-1;temp2[0][1]=0;temp2[0][2]=0;
            temp2[1][0]=0;temp2[1][1]=-1;temp2[1][2]=0;
            temp2[2][0]=0;temp2[2][1]=0;temp2[2][2]=1;

            matrix_mult(temp1,temp2,temp);      //translate & rotate

            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=x;temp1[2][1]=maxy;temp1[2][2]=1;

            matrix_mult(temp,temp1,temp2);      //translate back

            matrix_mult(f,temp2,temp);    //apply transformation

            createGraph();

            drawFigure(f);
            delay(1000);
            drawFigure(temp);
            delay(2000);
            cleardevice();
           
            //(e) scale by sx=2 & sy=1/2 about centroid
           
            float sx=2,sy=0.5;
            float cx,cy;
           
            //determine the centroid
            cx = (f[0][0]+f[1][0]+f[2][0])/3;
            cy = (f[0][1]+f[1][1]+f[2][1])/3;
           
            //finalT = [translate][scale][translate]'
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=-cx;temp1[2][1]=-cy; temp1[2][2]=1;
           
            temp2[0][0]=sx;temp2[0][1]=0;temp2[0][2]=0;
            temp2[1][0]=0;temp2[1][1]=sy;temp2[1][2]=0;
            temp2[2][0]=0;temp2[2][1]=0;temp2[2][2]=1;
           
            matrix_mult(temp1,temp2,temp);      //translate & scale
           
            temp1[0][0]=1;temp1[0][1]=0;temp1[0][2]=0;
            temp1[1][0]=0;temp1[1][1]=1;temp1[1][2]=0;
            temp1[2][0]=cx;temp1[2][1]=cy; temp1[2][2]=1;

            matrix_mult(temp,temp1,temp2);      //translate back
           
            matrix_mult(f,temp2,temp);    //apply transformation
           
            createGraph();
            drawFigure(f);
            delay(1000);
            drawFigure(temp);
            getch();
            closegraph();
 }

 //draws the figure provided as parameter
 void drawFigure(float vertex[][3]){

  int ox,oy;
 
  ox = getmaxx()/2;
  oy = getmaxy()/2;
 
  setcolor(RED);
  setlinestyle(SOLID_LINE,1,3);
 
  //draw the lines
  line(ox+vertex[0][0]*unitx,oy-vertex[0][1]*unity,ox+vertex[1][0]*unitx,oy-vertex[1][1]*unity);
  delay(500);
  line(ox+vertex[1][0]*unitx,oy-vertex[1][1]*unity,ox+vertex[2][0]*unitx,oy-vertex[2][1]*unity);
  delay(500);
  line(ox+vertex[2][0]*unitx,oy-vertex[2][1]*unity,ox+vertex[0][0]*unitx,oy-vertex[0][1]*unity);
  delay(500);
  }

 //function to compute matrix multiplication
 void matrix_mult(float A[][3],float B[][3],float C[][3]){
  int k,i,j;
  for(i=0;i<3;i++)
   for(j=0;j<3;j++){
    C[i][j] = 0;
    for(k=0;k<3;k++)
             C[i][j] = C[i][j] + A[i][k]*B[k][j];
   }
 }

 void display(float M[][3]){      //displays a 3X3 matrix
  int i,j;
  printf("\n\n");
  for(i=0;i<3;i++)
   for(j=0;j<3;j++)
    printf(" %f",M[i][j]);
  }
SAMPLE OUTPUT:


·         Reflection of the triangle around y = -x 

 
·         Translation along x axis –

 
·         Rotation by 180 degrees keeping the top most vertex fixed –
 
·         Scaling by sx = 2, sy = 0.5 about the centroid of the triangle –

 
·         Rotation by 60 degrees keeping top most vertex fixed –




 
                       


            

 



No comments:

Post a Comment

Do you think this information useful or was not up to the mark? Comment if you have any advices or suggestions about the post.