Tuesday, March 25, 2014

C++ program to implement 2D Transformations

Description :Transformations are used to position objects, to shape objects, to change viewing positions, and even to change how something is viewed.
There are 4 main types of transformations that one can perform in 2 dimensions:-translations,scaling,rotation,shearing.


Code :
#include<iostream.h>
#include<stdlib.h>
#include<dos.h>
#include<conio.h>

#include<graphics.h>
#include<math.h>
class POLYGON
{
private:
int p[10][10],Result[10][10],X[10][10];
public:
int accept_poly(int [][10]);
void draw_poly(int [][10],int);
void draw_polyfloat(float [][10],int);
void matmult(int [][10],int [][10],int,int,int,int [][10]);
void matmultfloat(float [][10],int [][10],int,int,int,float [][10]);
void shearing(int [][10],int);
void scaling(int [][10],int);
void rotation(int [][10],int);
void translation(int [][10],int);
void reflection(int [][10],int);
};
int POLYGON :: accept_poly(int p[][10])
{
int i,n;
cout << “\n\n\t\tEnter no.of vertices:”;
cin >> n;
for(i=0;i<n;i++)
{
cout << “\n\n\t\tEnter (x,y)Co-ordinate of point P” << i << “: “;
cin >> p[0][i] >> p[1][i];
p[2][i] = 1;
}
p[0][n] = p[0][0];
p[1][n] = p[1][0];
p[2][n] = 1;
for(i=0;i<n;i++)
{
cout<<”\n”;
for(int j=0;j<3;j++)
{
cout<<p[i][j]<<”\t”;
}
}
getch();
return n;
}
void POLYGON :: draw_poly(int p[][10], int n)
{
int i,gd = DETECT,gm;
initgraph(&gd,&gm,”e:\\TC\\BGI”);
line(320,0,320,480);
line(0,240,640,240);
for(i=0;i<n;i++)
{
if(i!=n-1)
line(p[0][i]+320, -p[1][i]+240, p[0][i+1]+320, -p[1][i+1]+240);
else
line(p[0][i]+320, -p[1][i]+240, p[0][0]+320, -p[1][0]+240);
}
getch();
closegraph();
}
void POLYGON :: draw_polyfloat(float p[][10], int n)
{
int i,gd = DETECT,gm;
initgraph(&gd,&gm,”e:\\TC\\BGI”);
line(320,0,320,480);
line(0,240,640,240);
for(i=0;i<n;i++)
{
if(i!=n-1)
line(int(p[0][i])+320, -int(p[1][i])+240, int(p[0][i+1])+320, -int(p[1][i+1])+240);
else
line(int(p[0][i])+320, -int(p[1][i])+240, int(p[0][0])+320, -int(p[1][0])+240);
}
getch();
closegraph();
}
void POLYGON :: matmult(int mat1[][10],int mat2[][10],int r1,int c1,int c2,int mat3[][10])
{
int i,j,k;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
mat3[i][j] = 0;
for(i=0;i<r1;i++)
for(j=0;j<c2;j++)
for(k=0;k<c1;k++)
mat3[i][j] = mat3[i][j]+(mat1[i][k] * mat2[k][j]);
mat3[c2][0] = mat3[0][0];
mat3[c2][1] = mat3[0][1];
mat3[c2][2] = mat3[0][2];
}
void POLYGON :: matmultfloat(float mat1[][10],int mat2[][10],int r1,int c1,int c2,float mat3[][10])
{
int i,j,k;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
mat3[i][j] = 0;
for(i=0;i<r1;i++)
for(j=0;j<c2;j++)
for(k=0;k<c1;k++)
mat3[i][j] = mat3[i][j]+(mat1[i][k] * mat2[k][j]);
mat3[c2][0] = mat3[0][0];
mat3[c2][1] = mat3[0][1];
mat3[c2][2] = mat3[0][2];
}
void POLYGON :: translation(int p[10][10],int n)
{
int tx,ty,i,j;
cout << “\n\n\t\tEnter X-Translation tx: “;
cin >> tx;
cout << “\n\n\t\tEnter Y-Translation ty: “;
cin >> ty;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
X[i][j] = 0;
X[0][0] = X[1][1] = X[2][2] = 1;
X[0][2] = tx;
X[1][2] = ty;
matmult(X,p,3,3,n,Result);
cout << “\n\n\t\tPolygon after Translation…”;
draw_poly(Result,n);
}
void POLYGON :: reflection(int p[][10],int n)
{
int type,i,j;
cout << “\n\n **** Reflection Types ****”;
cout << “\n\n\t\t1.About X-Axis \n\n\t\t2.About Y-Axis \n\n\t\t3.About Origin \
\n\n\t\t4.About Line y = x \n\n\t\t5.About Line y = -x \
\n\n\t\tEnter your choice(1-5): “;
cin >> type;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
if(i == j)
X[i][j] = 1;
else
X[i][j] = 0;
}
switch(type)
{
case 1:
X[1][1] = -1;
break;
case 2:
X[0][0] = -1;
break;
case 3:
X[1][1] = -1;
X[0][0] = -1;
break;
case 4:
X[1][1] = 0;
X[0][0] = 0;
X[1][0] = 1;
X[0][1] = 1;
break;
case 5:
X[1][1] = 0;
X[0][0] = 0;
X[1][0] = -1;
X[0][1] = -1;
break;
}
matmult(X,p,3,3,n,Result);
cout << “\n\n\t\tPolygon after Reflection…”;
draw_poly(Result,n);
}
void POLYGON :: rotation(int p[][10],int n)
{
float type,rotate[10][10],result[10][10],i,j,Ang,Sinang,Cosang;
cout << “\n\n\t\tEnter the angle of rotation in degrees: “;
cin >> Ang;
cout << “\n\n **** Rotation Types ****”;
cout << “\n\n\t\t1.Clockwise Rotation \n\n\t\t2.Anti-Clockwise Rotation “;
cout << “\n\n\t\tEnter your choice(1-2): “;
cin >> type;
Ang = (Ang * 6.2832)/360;
Sinang = sin(Ang);
Cosang = cos(Ang);
for(i=0;i<3;i++)
for(j=0;j<3;j++)
rotate[i][j] = 0;
rotate[0][0] = rotate[1][1] = Cosang;
rotate[0][1] = rotate[1][0] = Sinang;
rotate[2][2] = 1;
if(type == 1)
rotate[1][0] = -Sinang;
else
rotate[0][1] = Sinang;
matmultfloat(rotate,p,3,3,n,result);
cout << “\n\n\t\tPolygon after Rotation…”;
draw_polyfloat(result,n);
}
void POLYGON :: scaling(int p[][10],int n)
{
float Sx,Sy,result[10][10],scale[10][10],i,j;
cout << “\n\n\t\tEnter X-Scaling Sx: “;
cin >> Sx;
cout << “\n\n\t\tEnter Y-Scaling Sy: “;
cin >> Sy;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
scale[i][j] = 0;
scale[0][0] = Sx;
scale[1][1] = Sy;
scale[2][2] = 1;
matmultfloat(scale,p,3,3,n,result);
cout << “\n\n\t\tPolygon after Scaling…”;
draw_polyfloat(result,n);
}
void POLYGON :: shearing(int p[][10],int n)
{
int Sx,Sy,type,i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
if(i == j)
X[i][j] = 1;
else
X[i][j] = 0;
}
cout << “\n\n **** Shearing Types ****”;
cout << “\n\n\t\t1.X-Direction Shear \n\n\t\t2.Y-Direction Shear “;
cout << “\n\n\t\tEnter your choice(1-2): “;
cin >> type;
if(type == 1)
{
cout << “\n\n\t\tEnter X-Shear Sx: “;
cin >> Sx;
X[0][1] = Sx;
}
else
{
cout << “\n\n\t\tEnter Y-Shear Sy: “;
cin >> Sy;
X[1][0] = Sy;
}
matmult(X,p,3,3,n,Result);
cout << “\n\n\t\tPolygon after Shearing…”;
draw_poly(Result,n);
}
int menu()
{
int ch;
clrscr();
cout << “\n\n **** 2-D TRANSFORMATION ****”;
cout << “\n\n\t\t1.Translation \n\n\t\t2.Scaling \n\n\t\t3.Rotation \
\
n\n\t\t4.Reflection \n\n\t\t5.Shearing \n\n\t\t6.Exit”;
cout<<”\n\n\tEnter your choice(1-6): “;
cin >> ch;
return ch;
}
void main()
{
int ch,n,p[10][10];
POLYGON p1;
clrscr();
cout << “\n\n **** 2-D TRANSFORMATION ****”;
n = p1.accept_poly(p);
clrscr();
cout << “\n\n\t\tOriginal Polygon …”;
p1.draw_poly(p,n);
do
{
ch = menu();
switch(ch)
{
case 1:
p1.translation(p,n);
break;
case 2:
p1.scaling(p,n);
break;
case 3:
p1.rotation(p,n);
break;
case 4:
p1.reflection(p,n);
break;
case 5:
p1.shearing(p,n);
break;
case 6:
exit(0);
}
}while(ch!=6);
getch();
}

A program for filling a polygon using scan-fill method.

Description :For each scan-line:
– Locate the intersection of the scan-line with the edges
– Sort the intersection points from left to right.
– Draw the interiors intersection points pairwise.


Code :

#include <conio.h>
#include <iostream.h>
#include <graphics.h>
#include <dos.h>
#include <stdlib.h>
//Declaration of class point
class point
{
public:
int x,y;
};
//class for polygon
class poly
{
private:
point p[20];
int inter[20],x,y;
int v,xmin,ymin,xmax,ymax;
public:
int c;
void read();
void calcs();
void display();
void ints(float);
void intsx(float);
void sort(int);
void sort(int,int);
};
//DEFINE READ FUNCTION
void poly::read()
{
cout<<”\n\t SCAN_FILL ALGORITHM”;
cout<<”\n Enter the no of vertices of polygon:”;
cin>>v;
if(v>2)
{
for(int i=0;i<v; i++) //ACCEPT THE VERTICES
{
cout<<”\nEnter the co-ordinate no. – “<<i+1<<” : “;
cout<<”\n\tx”<<(i+1)<<”=”;
cin>>p[i].x;
cout<<”\n\ty”<<(i+1)<<”=”;
cin>>p[i].y;
}
p[i].x=p[0].x;
p[i].y=p[0].y;
xmin=xmax=p[0].x;
ymin=ymax=p[0].y;
}
else
cout<<”\n Enter valid no. of vertices.”;
}
//FUNCTION FOR FINDING
void poly::calcs()
{ //MAX,MIN
for(int i=0;i<v;i++)
{
if(xmin>p[i].x)
xmin=p[i].x;
if(xmax<p[i].x)
xmax=p[i].x;
if(ymin>p[i].y)
ymin=p[i].y;
if(ymax<p[i].y)
ymax=p[i].y;
}
}
//DISPLAY FUNCTION
void poly::display()
{
int ch1;
char ch=’y';
float s,s2;
do
{
cout<<”\n\nMENU:”;
cout<<”\n\n\t1 . Solid Fill “;
cout<<”\n\n\t2 . Exit “;
cout<<”\n\nEnter your choice:”;
cin>>ch1;
switch(ch1)
{
case 1:
s=ymin+0.5;
delay(10);
cleardevice();
while(s<=ymax)
{
ints(s);
sort(s,1);
s++;
}
break;
case 2:
exit(0);
}
cout<<”\n\nDo you want to continue?: “;
cin>>ch;
}while(ch==’y’ || ch==’Y');
}
void poly::ints(float z) //DEFINE FUNCTION INTS
{
int x1,x2,y1,y2,temp;
c=0;
for(int i=0;i<v;i++)
{
x1=p[i].x;
y1=p[i].y;
x2=p[i+1].x;
y2=p[i+1].y;
if(y2<y1)
{
temp=x1;
x1=x2;
x2=temp;
temp=y1;
y1=y2;
y2=temp;
}
if(z<=y2&&z>=y1)
{
if((y1-y2)==0)
x=x1;
else
{
x=((x2-x1)*(z-y1))/(y2-y1);
x=x+x1;
}
if(x<=xmax && x>=xmin)
inter[c++]=x;
}
}
}
void poly::sort(int z,int w) //SORT FUNCTION
{
int temp,j;
for(int i=0;i<c;i++)
{
for(j=i+1;j<c;j++)
{
if(inter[i]>inter[j])
{
temp=inter[i];
inter[i]=inter[j];
inter[j]=temp;
}
}
}
if(w==1)
{
for(i=0;i<v;i++)
{
line(p[i].x,p[i].y,p[i+1].x,p[i+1].y);
}
delay(10);
for(i=0; i<c;i+=2)
{
delay(10);
line(inter[i],z,inter[i+1],z);
}
}
}
void main() //START OF MAIN
{
int gd=DETECT,gm,cl;
initgraph(&gd,&gm,”e:\\tc\\BGI”);
cleardevice();
poly x;
x.read();
x.calcs();
cleardevice();
cout<<”\n\tEnter the colour u want:(0-15)–>”; //Selecting colour
cin>>cl;
cleardevice();
setcolor(cl);
x.display();
closegraph(); //CLOSE OF GRAPH
cout<<”\n\nC=”<<x.c;
getch();
}

PROGRAM TO DRAW LINE & CIRCLE USING DDA & BRESENHAM’S ALGORITHM USING C++

Bresenham’s algorithm: It is commonly used to draw lines on a computer screen, as it uses only integer addition, subtraction ,bit shifting all of which are very cheap operations in standard computer architectures.
DDA: Digital Differential Analyzer is a scan conversion line algorithm based on calculating either dy or dx. We sample the line at unit intervals in one coordinate & determine corresponding integer values nearest to the line path for the other coordinate. DDAs are used for rasterization of lines, triangles and polygons.
  
Code :
#include<iostream.h>
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
#include<math.h>
#include<dos.h>
#include<stdio.h>
#include<process.h>
class draw
{
float x,y,x1,y1,x2,y2,dx,dy,xinc,yinc,g,temp,m;
int steps;
public:
void ddaline();
void bline();
void ddacircle();
void bcircle();
};
void draw::ddaline()
{
int i;
cout<<”\n Please enter x1: “;
cin>>x1;
cout<<”\n Please enter y1: “;
cin>>y1;
cout<<”\n Please enter x2: “;
cin>>x2;
cout<<”\n Please enter y2: “;
cin>>y2;
dx=abs(x2-x1);
dy=abs(y2-y1);
clrscr();
if(dx>dy)
steps=dx;
else
steps=dy;
x=x1;
y=y1;
xinc=dx/steps;
yinc=dy/steps;
for(i=0;i<steps;i++)
{
putpixel(x+5.0,y+5.0,RED);
delay(10);
x=x+xinc;
y=y+yinc;
}
}
void draw::bline()
{
int i;
cout<<”\n Please enter x1: “;
cin>>x1;
cout<<”\n Please enter y1: “;
cin>>y1;
cout<<”\n Please enter x2: “;
cin>>x2;
cout<<”\n Please enter y2: “;
cin>>y2;
dx=x2-x1;
dy=y2-y1;
g=(2*dy)-dx;
x=x1;
y=y1;
m=dy/dx;
x=x1;
y=y1;
if(m>1)
{
temp=x;
x=y;
y=temp;
}
for(i=0;i<dx;i++)
{
putpixel(x,y,19);
delay(10);
x++;
if(g>0)
{
y++;
g=g+(2*dy)-(2*dx);
}
else
g=g+(2*dy);
}
}
void draw::ddacircle()
{
float rad,start_x=rad,start_y=0,e;
int p,n=0;
cout<<”\n\nEnter the radius of circle: “;
cin>>rad;
x1=0;
x2=rad;
x1=start_x;
y1=start_y;
do
{
p=pow(2,n);
n++;
}while(p<rad);
e=1/(pow(2,n-1));
do
{
x2=x1+e*y1;
y2=y1-e*x2;
delay(10);
putpixel(200+x2,200+y2,3);
x1=x2;
y1=y2;
}while( (y1-start_y)<e || (start_x-x1)>e );
}
void draw::bcircle()
{
float rad;
float d=3-(2*rad);
cout<<”\n\nEnter the radius of circle: “;
cin>>rad;
x2=0;
y2=rad;
do
{
delay(15);
putpixel(200+x2,200+y2,1);
putpixel(200+y2,200+x2,2);
putpixel(200-y2,200+x2,3);
putpixel(200+x2,200-y2,4);
putpixel(200-x2,200-y2,5);
putpixel(200-y2,200-x2,6);
putpixel(200+y2,200-x2,7);
putpixel(200-x2,200+y2,8);
if(d<0)
{
d=d+(4*x2)+6;
}
else
{
d=d+(4*(x2-y2))+10;
y2–;
}
x2++;
}while(x2<y2);
}
void main()
{
draw obj;
int gd=DETECT,gm;
int choice;
char ans;
float rad;
clrscr();
initgraph(&gd,&gm,”C:\\TC\\BGI”);
do
{
cout<<”\n\n MENU:”;
cout<<”\n\n\t1.DDA Line\n\n\t2.Bresenham’s Line\n\n\t3.DDA Circle\n\n\t4.Bresenham’s Circle”;
cout<<”\n\nEnter your choice: “;
cin>>choice;
switch(choice)
{
case 1:
obj.ddaline();
break;
case 2:
obj.bline();
break;
case 3:
obj.ddacircle();
break;
case 4:
obj.bcircle();
break;
default:
cout<<”\n\nPlease Enter Correct Choice: “;
break;
}
cout<<”\n\nDo you want to continue?(y/n): “;
fflush(stdin);
cin>>ans;
}while(ans==’y’ || ans==’Y');
getch();
closegraph();
}