You are on page 1of 59

COMPUTER GRAPHICS (CO-313 (C-2))

LAB

Name: Amit Kumar


Roll No.: 2K15/CO/021
INDEX
S. No. Experiment Date Signature
1. Program to implement DDA
algorithm.
2. Program to implement Bresenham
algorithm.
3. Program to implement Mid-Point
Circle Algorithm
4. Program to implement Mid-Point
Ellipse Algorithm
5. Program To implement Flood Fill
Algorithm
6. Program To implement Boundary Fill
Algorithm
7. Program To implement Cohen-
Sutherland Line Clipping Algorithm
8. Program To implement Clipping of
Polygon Algorithm
9. Program To implement Translation,
Rotation and Scaling of an object.
10. Program To implement Liang Barsky
Line Clipping algorithm
Experiment-1

Aim:
Program to implement DDA algorithm.

Description:
In a 2-D plane if we connect two points (x0, y0) and (x1, y1), we get a
line segment. But in computer graphics we can’t directly join any two
coordinate points, for that we calculate intermediate point’s coordinate
and put a pixel for each intermediate point, of the desired color with
help of functions. For generating any line segment we need
intermediate points and for calculating them we have can use a basic
algorithm called DDA (Digital differential analyzer) line generating
algorithm.
Algorithm:
Digital Differential Analyzer (DDA) algorithm is the simple line
generation algorithm which is explained step by step here.

Step 1 − Get the input of two end points (X0, Y0) and (X1, Y1).
Step 2 − Calculate the difference between two end points.

dx = X1 - X0
dy = Y1 - Y0

Step 3 − Based on the calculated difference in step-2, you need to identify


the number of steps to put pixel. If dx>dy, then you need more steps in x
coordinate; otherwise in y coordinate.

if (absolute(dx) > absolute(dy))

Steps = absolute(dx);

else

Steps = absolute(dy);

Step 4 − Calculate the increment in x coordinate and y coordinate.

Xincrement = dx / (float) steps;


Yincrement = dy / (float) steps;

Step 5 − Put the pixel by successfully incrementing x and y coordinates


accordingly and complete the drawing of the line.

for ( int v = 0 ; v < Steps ; v++)

x = x + Xincrement ;

y = y + Yincrement ;

putpixel (Round(x), Round(y)) ;


}

Code:
Result:
Discussion:
Advantages:
1. It is the simplest algorithm and it does not require special skills for
implementation.
2. It is a faster method for calculating pixel positions than the direct use of equation
y = mx + b. It eliminates the multiplication in the equation by making use of raster
characteristics.
Disadvantages:
1. Floating point arithmetic in DDA algorithm is still time-consuming.
2. The algorithm is orientation dependent. Hence end point accuracy is poor.

Findings and Learnings:


1. The DDA Algorithm is much faster than the direct line equation as there's
no floating point calculations involved.
2. It's the simplest algorithm and does not require and special skills for
implementation.
3. It's orientation dependent, due to which end point accuracy is poor.
4. Floating point additions are still very expensive operations.
5. The cumulative errors due to limited floating point precision may cause the
calculated points to drift away from the actual line.
Experiment-2

Aim:
Program to implement Bresenham algorithm.

Description:
An accurate and efficient raster line-generating algorithm, developed by
Bresenham, which uses only incremental integer calculations. In addition, it can
also be adapted to display circles and other curves. The basic principle is to find
the optimum raster location to represent the straight line. To accomplish this, the
algorithm always increments x/y by one unit based on the flow of the line. Then,
the increment in other variable is found on the basis of the distance between the
actual line location & the nearest pixel.

Algorithm:
1. Input the two line endpoints and store the left endpoint in (x0, y0).
2. Set the color for frame-buffer position (x0, y0); i.e., plot the first point.
3. calculate δx, δy, 2δy and 2δy-δx
4. obtain P0 as follows:
5. P0 = 2δy - δx
6. δx = |X2-X1|
7. δy = |Y2-Y1|
8. At each xk along the line, starting at k = 0, perform the following test:
9. if(Pk < 0):
10. next_point = (Xk+1,Yk)
11. Pk+1 = Pk + 2δy
12. else:
13. next_point = (Xk+1,Yk+1)
14. Pk+1 = Pk + 2δy -2δx
15. Repeat lines 9-14 for δx-1 times.
Code:
Result:

Findings and Learnings:


1. The Bresenham Algorithm only uses integers and operations on them,
therefore it is much faster and precise.
2. As there is no rounding function there's not scope for the line to move
away from the actual line.
3. Compared to DDA it's a faster increment algorithm.
Experiment-3

Aim:
To draw a circle using the Mid-Point Algorithm

Description:
It runs the same screen pass as in the Bresenham’s Algorithm and in each screen
pass 8 points are drawn simultaneously. This is possible by the dual-axis symmetry
of the circle. Only the first half of the first quadrant is calculated, rest of the
points are their symmetric reflections along different axis.

Algorithm:
1. Input radius r and circle center (xc , yc )
2. Set the coordinates for first point as:
3. (X0,Y0) = (0,r)
4. Calculate the initial value of the decision parameter as:
5. P0 = 5/4 - r
6. At each xk position, starting at k = 0, perform the following test:
7. if(Pk < 0):
8. next_point = (Xk+1,Yk)
9. Pk+1 = Pk + 2Xk+1 + 1
10. else:
11. next_point = (Xk+1, Yk-1)
12. Pk+1 = Pk + 2Xk+1 + 1 - 2Yk+1
13. //2xk+1 = 2xk + 2 and 2yk+1 = 2yk − 2.
14. Determine symmetry points in the other seven octants.
15. Move each calculated pixel position (x, y) onto the circular path centered at (xc , yc ) and plot the coordinate
values as follows:
16. x = x + Xc
17. y = y + Yc
18. repeat Lines 6-17 until x>=y
Code:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
void pixel(int xc,int yc,int x,int y);
void main()
{
int gd=DETECT,gm,xc,yc,r,x,y,Pk;
clrscr();
initgraph(&gd,&gm,"c:\\turboc3\\bgi ");
printf("*** Mid-Point Subdivision algorithm of circle ***\n");
printf("Enter the value of Xc\t");
scanf("%d",&xc);
printf("Enter the value of Yc \t");
scanf("%d",&yc);
printf("Enter the Radius of circle\t");
scanf("%d",&r);
x=0;
y=r;
Pk=1-r;
pixel(xc,yc,x,y);
while(x<y)
{
if(Pk<0)
{
x=x+1;
Pk=Pk+(2*x)+1;
}
else
{
x=x+1;
y=y-1;
Pk=Pk+(2*x)-(2*y)+1;
}
pixel(xc,yc,x,y);
}
getch();
closegraph();
}
void pixel(int xc,int yc,int x,int y)
{
putpixel(xc+x,yc+y,7);
putpixel(xc+y,yc+x,7);
putpixel(xc-y,yc+x,7);
putpixel(xc-x,yc+y,7);
putpixel(xc-x,yc-y,7);
putpixel(xc-y,yc-x,7);
putpixel(xc+y,yc-x,7);
putpixel(xc+x,yc-y,7);

Results:

Findings and Learnings:


1. The midpoint method is used for deriving efficient scan-conversion
algorithms to draw geometric curves on raster displays.
2. The method is general and is used to transform the nonparametric
equation f(x,y) = 0, which describes the curve, into an algorithms that draws
the curve.
3. Time consumption is high.
4. The distance between the pixels is not equal so we won’t get smooth circle.
Experiment-4

Aim:
To draw an ellipse using the Mid-Point Algorithm

Description:
● Ellipses in Computer Graphics:

o Just like lines, ellipses are another primitive shape used in computer
graphics.

o An ellipse is defined as the set of points such that the sum of the
distances from two fixed positions (foci) is the same for all points. If
the distances to the two foci from any point on the ellipse are labeled
d 1 and d 2 , then the general equation of an ellipse can be stated as :

o Expressing distances d 1 and d 2 in terms of the focal coordinates and


, we have:

o Ellipse equations are greatly simplified if the major and minor axes
are oriented to align with the coordinate axes. An ellipse in "standard
position" has major and minor axes oriented parallel to the x and y
axes respectively.

o Parameter rx labels the semi-major axis, and parameter ry labels the


semi-minor axis. The equation of the ellipse can be written in terms
of the ellipse center coordinates and parameters rx and ry as :
o Alternatively, one could use the polar coordinates, but yet again they
come at a higher computational cost, thus more efficient algorithms
have been designed to draw ellipses.

Algorithm:
1. Input radii rx and ry and ellipse center (xc, yc)
2. Set the coordinates for first point as:
3. (X0,Y0) = (0,r)
4. Calculate the initial value of the decision parameter as:
5. P10 = ry^2 + rx^2/4 - rx^2ry
6. At each xk position in octant 1, starting at k = 0, perform the following test:
7. if (P1k < 0):
8. next_point = (Xk+1,Yk)
9. P1 (k+1) = P1k + 2ry^2x(k+1) + ry^2
10. Else:
11. next_point = (Xk+1, Yk-1)
12. P1(k+1) = P1k + 2ry^2x(k+1) + ry^2 - 2rx^2y(k+1)
14. Determine symmetry points in the other three octants.
15. Move each calculated pixel position (x, y) onto the circular path centered at (xc , yc ) and
plot the coordinate values as follows:
16. x = x + Xc
17. y = y + Yc
18. Repeat Lines 7-17 until 2ry^2x >= 2rx^2y.
19. Calculate the initial value of the decision parameter as:
20. p20 = ry^2(x0 + 1/2)^2 + rx^2(y0 - 1)^2 - rx^2ry^2
21. At each xk position in octant 2, starting at k = 0, perform the following test:
22. if(P2k > 0):
23. next_point = (Xk,Yk-1)
24. P2(k+1) = P2k - 2rx^2y(k+1) + rx^2
25. else:
26. next_point = (Xk+1,Yk-1)
27. P2(k+1) = P2k - 2rx^2y(k+1) + rx^2 - 2rx^2y(k+1)
28. Determine symmetry points in the other three octants.
29. Move each calculated pixel position (x, y) onto the circular path centered at (xc , yc ) and
plot the coordinate values as follows:
30. x = x + Xc
31. y = y + Yc
32. Repeat lines 22 - 31 till y > 0

Code:
#include<conio.h>
#include<graphics.h>
#include<math.h>
void disp();
float x,y;
int xc,yc;
void main()
{
int gd=DETECT,gm;
int a,b;
float p1,p2;
clrscr();
initgraph(&gd,&gm,"");
scanf("%d%d",&xc,&yc);
scanf("%d%d",&a,&b);
x=0;y=b;
disp();
p1=(b*b)-(a*a*b)+(a*a)/4;

while((2.0*b*b*x)<=(2.0*a*a*y))
{
x++;
if(p1<=0)
p1=p1+(2.0*b*b*x)+(b*b);
else
{
y--;
p1=p1+(2.0*b*b*x)+(b*b)-(2.0*a*a*y);
}
disp();
x=-x;
disp();
x=-x;
}
x=a;
y=0;
disp();
p2=(a*a)+2.0*(b*b*a)+(b*b)/4;

while((2.0*b*b*x)>(2.0*a*a*y))
{
y++;
if(p2>0)
p2=p2+(a*a)-(2.0*a*a*y);
else
{
x--;
p2=p2+(2.0*b*b*x)-(2.0*a*a*y)+(a*a);
}
disp();
y=-y;
disp();
y=-y;
}
getch();
closegraph();
}

void disp()
{
putpixel(xc+x,yc+y,10);
putpixel(xc-x,yc+y,10);
putpixel(xc+x,yc-y,10);
putpixel(xc+x,yc-y,10);
}
Result:

Findings and Learnings:


1. The midpoint method is used for deriving efficient scan-conversion
algorithms to draw geometric curves on raster displays.
2. The method is general and is used to transform the nonparametric
equation f(x,y) = 0, which describes the curve, into an algorithms that draws
the curve.
3. Time consumption is high.
4. The distance between the pixels is not equal so we won’t get smooth circle.
Experiment-5

Aim:
To write a program and implement Flood Fill Algorithm

Description:
Sometimes we come across an object where we want to fill the area and its
boundary with different colors. We can paint such objects with a specified interior
color instead of searching for particular boundary color as in boundary filling
algorithm.

Instead of relying on the boundary of the object, it relies on the fill color. In other
words, it replaces the interior color of the object with the fill color. When no more
pixels of the original interior color exist, the algorithm is completed.

In Flood Fill algorithm we start with some seed and examine the neighboring
pixels, however pixels are checked for a specified interior color instead of
boundary color and is replaced by a new color. It can be done using 4 connected
or 8 connected region method.
ALGORITHM:
Step 1 − Initialize the value of seed point (seedx, seedy), fcolor and dcol.

Step 2 − Define the boundary values of the polygon.

Step 3 − Check if the current seed point is of default color, then repeat the steps 4 and 5 till the
boundary pixels reached.

Ifgetpixel(x, y)=dcol then repeat step 4and5

Step 4 − Change the default color with the fill color at the seed point.

setPixel(seedx, seedy, fcol)

Step 5 − Recursively follow the procedure with four neighborhood points.

FloodFill (seedx – 1, seedy, fcol, dcol)


FloodFill (seedx + 1, seedy, fcol, dcol)
FloodFill (seedx, seedy - 1, fcol, dcol)
FloodFill (seedx – 1, seedy + 1, fcol, dcol)

Step 6 − Exit

There is a problem with this technique. Consider the case as shown below where we tried to fill
the entire region. Here, the image is filled only partially. In such cases, 4-connected pixels
technique cannot be used.
CODE:

#include<stdio.h>
#include<graphics.h>
#include<dos.h>

voidfloodFill(intx,inty,intoldcolor,intnewcolor)
{
if(getpixel(x,y) == oldcolor)
{
putpixel(x,y,newcolor);
floodFill(x+1,y,oldcolor,newcolor);
floodFill(x,y+1,oldcolor,newcolor);
floodFill(x-1,y,oldcolor,newcolor);
floodFill(x,y-1,oldcolor,newcolor);
}
}
//getpixel(x,y) gives the color of specified pixel

int main()
{
intgm,gd=DETECT,radius;
intx,y;

printf("Enter x and y positions for circle\n");


scanf("%d%d",&x,&y);
printf("Enter radius of circle\n");
scanf("%d",&radius);

initgraph(&gd,&gm,"c:\\turboc3\\bgi");
circle(x,y,radius);
floodFill(x,y,0,15);
delay(5000);
closegraph();

return 0;
}
OUTPUT:

FINDING AND LEARNING:


We can modify findFill() method to reduce storage requirements of the stack by
filling horizontal pixel spans ,i.e., we stack only beginning positions for those pixel
spans having oldcolour .In this modified version, starting at the first position of
each span, the pixel values are replaced until a value other than oldcolour is
encountered. We can also show an area bordered by several different color
regions too.
Experiment-6

Aim:
To implement Boundary Fill Algorithm

Description:
The boundary fill algorithm works as its name. This algorithm picks a point inside
an object and starts to fill until it hits the boundary of the object. The color of the
boundary and the color that we fill should be different for this algorithm to work.
In this algorithm, we assume that color of the boundary is same for the entire
object. The boundary fill algorithm can be implemented by 4-connected pixels or
8-connected pixels.

Algorithm:
1. Create a function named as boundaryfill with 4 parameters
(x,y,f_color,b_color).

void boundaryfill(int x,int y,int


f_color,int b_color)
{
if(getpixel(x,y)!=b_color &&
getpixel(x,y)!=f_color)
{
putpixel(x,y,f_color);
boundaryfill(x+1,y,f_color,b_color)
;
boundaryfill(x,y+1,f_color,b_color)
;
boundaryfill(x-1,y,f_color,b_color);
boundaryfill(x,y-1,f_color,b_color);
}
}
2. Call it recursively until the boundary pixels are reached.
3. Stop.

Code:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<dos.h>
void fill_right(int x,int y);
void fill_left(int x,int y);
void main()
{
int gd=DETECT,gm,x,y,n,i;
clrscr();
initgraph(&gd,&gm,"c:\\turboc3\\bgi");
printf("*** Boundary Fill algorithm ***");
/*- draw object -*/
line (50,50,200,50);
line (200,50,200,300);
line (200,300,50,300);
line (50,300,50,50);
/*- set seed point -*/
x=100; y=100;
fill_right(x,y);
fill_left(x-1,y);
getch();
}
void fill_right(int x,int y)
{
if((getpixel(x,y) != WHITE)&&(getpixel(x,y) != RED))
{
putpixel(x,y,RED);
fill_right(++x,y); x=x-1;
fill_right(x,y-1);
fill_right(x,y+1);
}
delay(1);
}
void fill_left(int x,int y)
{
if((getpixel(x,y) != WHITE)&&(getpixel(x,y) != RED))
{
putpixel(x,y,RED);
fill_left(--x,y); x=x+1;
fill_left(x,y-1);
fill_left(x,y+1);
}
delay(1);
}

Result:

Findings and Learnings:

1. Boundary Fill is used for the coloring figures in computer graphics. Here,
area gets colored with pixels of a chosen color as boundary this giving the
technique its name.
2. Boundary fill fills the chosen area with a color until the given colored
boundary is found.
3. This algorithm is also recursive in nature as the function returns when the
pixel to be colored is the boundary color or is already the fill color.

Experiment-7

Aim:
To implement Cohen-Sutherland Line Clipping Algorithm

Description:
This algorithm uses the clipping window as shown in the following figure. The
minimum coordinate for the clipping region is (XWmin, YWmin) and the maximum
coordinate for the clipping region is (XWmax, YWmax).
We will use 4-bits to divide the entire region. These 4 bits represent the Top,
Bottom, Right, and Left of the region as shown in the following figure. Here,
the TOP and LEFT bit is set to 1 because it is the TOP-LEFT corner.
There are 3 possibilities for the line −
● Line can be completely inside the window (This line should be accepted).
● Line can be completely outside of the window (This line will be completely
removed from the region).
● Line can be partially inside the window (We will find intersection point and
draw only that portion of line that is inside region).

Algorithm:

1. Assign a region code for each endpoints.


2 − If both endpoints have a region code 0000 then accept this line.
3 − Else, perform the logical AND operation for both region codes.
3.1 − If the result is not 0000, then reject the line.
3.2 − Else you need clipping.
3.2.1 − Choose an endpoint of the line that is outside the window.
3.2.2 − Find the intersection point at the window boundary (base on
region code).
3.2.3 − Replace endpoint with the intersection point and update the
region code.
3.2.4 − Repeat step 2 until we find a clipped line either trivially
accepted or trivially rejected.
4 − Repeat step 1 for other lines.

Code:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<graphics.h>
#include<dos.h>

typedef struct coordinate


{
int x,y;
char code[4];
}PT;

void drawwindow();
void drawline(PT p1,PT p2);
PT setcode(PT p);
int visibility(PT p1,PT p2);
PT resetendpt(PT p1,PT p2);
void main()
{
int gd=DETECT,v,gm;
PT p1,p2,p3,p4,ptemp;

printf("\nEnter x1 and y1\n");


scanf("%d %d",&p1.x,&p1.y);
printf("\nEnter x2 and y2\n");
scanf("%d %d",&p2.x,&p2.y);

initgraph(&gd,&gm,"c:\\turboc3\\bgi");
drawwindow();
delay(500);

drawline(p1,p2);
delay(500);
cleardevice();

delay(500);
p1=setcode(p1);
p2=setcode(p2);
v=visibility(p1,p2);
delay(500);

switch(v)
{
case 0: drawwindow();
delay(500);
drawline(p1,p2);
break;
case 1: drawwindow();
delay(500);
break;
case 2: p3=resetendpt(p1,p2);
p4=resetendpt(p2,p1);
drawwindow();
delay(500);
drawline(p3,p4);
break;
}

delay(5000);
closegraph();
}
void drawwindow()
{
line(150,100,450,100);
line(450,100,450,350);
line(450,350,150,350);
line(150,350,150,100);
}

void drawline(PT p1,PT p2)


{
line(p1.x,p1.y,p2.x,p2.y);
}

PT setcode(PT p) //for setting the 4 bit code


{
PT ptemp;

if(p.y<100)
ptemp.code[0]='1'; //Top
else
ptemp.code[0]='0';

if(p.y>350)
ptemp.code[1]='1'; //Bottom
else
ptemp.code[1]='0';

if(p.x>450)
ptemp.code[2]='1'; //Right
else
ptemp.code[2]='0';

if(p.x<150)
ptemp.code[3]='1'; //Left
else
ptemp.code[3]='0';

ptemp.x=p.x;
ptemp.y=p.y;

return(ptemp);
}
int visibility(PT p1,PT p2)
{
int i,flag=0;

for(i=0;i<4;i++)
{
if((p1.code[i]!='0') || (p2.code[i]!='0'))
flag=1;
}

if(flag==0)
return(0);

for(i=0;i<4;i++)
{
if((p1.code[i]==p2.code[i]) && (p1.code[i]=='1'))
flag='0';
}

if(flag==0)
return(1);

return(2);
}

PT resetendpt(PT p1,PT p2)


{
PT temp;
int x,y,i;
float m,k;

if(p1.code[3]=='1')
x=150;

if(p1.code[2]=='1')
x=450;

if((p1.code[3]=='1') || (p1.code[2]=='1'))
{
m=(float)(p2.y-p1.y)/(p2.x-p1.x);
k=(p1.y+(m*(x-p1.x)));
temp.y=k;
temp.x=x;
for(i=0;i<4;i++)
temp.code[i]=p1.code[i];

if(temp.y<=350 && temp.y>=100)


return (temp);
}

if(p1.code[0]=='1')
y=100;

if(p1.code[1]=='1')
y=350;

if((p1.code[0]=='1') || (p1.code[1]=='1'))
{
m=(float)(p2.y-p1.y)/(p2.x-p1.x);
k=(float)p1.x+(float)(y-p1.y)/m;
temp.x=k;
temp.y=y;

for(i=0;i<4;i++)
temp.code[i]=p1.code[i];

return(temp);
}
else
return(p1);
}
Result:

Before clipping:

After clipping:

Findings and Learning:


The algorithm divides a two-dimensional space into 9 regions and then efficiently
determines the lines and portions of lines that are visible in the central region of
interest (the viewport).
Cohen Sutherland Line Clipping Algorithm is used to clip certain portions of the
display according to a given window.

Experiment-8

Aim:
Write a program to implement clipping of Polygon Algorithm.

Description:

● The Sutherland - Hodgeman algorithm performs a clipping of a polygon


against each window edge in turn. It accepts an ordered sequence of
vertices v1, v2, v3 ... vn and puts out a set of vertices defining the clipped
polygon. Just like the Cohen-Sutherland algorithm this uses a divide and
conquer approach.
● The following types of edges are encountered:
o Edges that are totally inside the clip window. - add the second inside
vertex point
o Edges that are leaving the clip window. - add the intersection point
as a vertex
o Edges that are entirely outside the clip window. - add nothing to the
vertex output list
o Edges that are entering the clip window. - save the intersection and
inside points as vertices
● The clipping is checked:
o Clipping against the left side of the clip window.

o Clipping against the top side of the clip window.

o Clipping against the right side of the clip window.


o Clipping against the bottom side of the clip window.

Algorithm:
1. for each edge test the following cases:
i. if v1 in outside and v2 inside:
a. find intersection
b. store inner v and intersection
ii. if v1 and v2 are inside:
a. save both
iii. if v1 is inside and v2 outside:
a. find intersection
b. store only the intersection
iv. if v1 and v2 are outside
a. ignore both

Code:

#include<iostream>
#include<conio.h>
#include<graphics.h>
#define round(a) ((int)(a+0.5))
using namespace std;

int k;

float xmin,ymin,xmax,ymax,arr[20],m;

void clipl(float x1,float y1,float x2,float y2)

if(x2-x1)

m=(y2-y1)/(x2-x1);

else

m=100000;
if(x1 >= xmin && x2 >= xmin)

arr[k]=x2;

arr[k+1]=y2;

k+=2;

if(x1 < xmin && x2 >= xmin)

arr[k]=xmin;

arr[k+1]=y1+m*(xmin-x1);

arr[k+2]=x2;

arr[k+3]=y2;

k+=4;

if(x1 >= xmin && x2 < xmin)

arr[k]=xmin;

arr[k+1]=y1+m*(xmin-x1);

k+=2;

void clipt(float x1,float y1,float x2,float y2)

if(y2-y1)

m=(x2-x1)/(y2-y1);

else

m=100000;

if(y1 <= ymax && y2 <= ymax)

{
arr[k]=x2;

arr[k+1]=y2;

k+=2;

if(y1 > ymax && y2 <= ymax)

arr[k]=x1+m*(ymax-y1);

arr[k+1]=ymax;

arr[k+2]=x2;

arr[k+3]=y2;

k+=4;

if(y1 <= ymax && y2 > ymax)

arr[k]=x1+m*(ymax-y1);

arr[k+1]=ymax;

k+=2;

void clipr(float x1,float y1,float x2,float y2)

if(x2-x1)

m=(y2-y1)/(x2-x1);

else

m=100000;

if(x1 <= xmax && x2 <= xmax)

arr[k]=x2;

arr[k+1]=y2;
k+=2;

if(x1 > xmax && x2 <= xmax)

arr[k]=xmax;

arr[k+1]=y1+m*(xmax-x1);

arr[k+2]=x2;

arr[k+3]=y2;

k+=4;

if(x1 <= xmax && x2 > xmax)

arr[k]=xmax;

arr[k+1]=y1+m*(xmax-x1);

k+=2;

void clipb(float x1,float y1,float x2,float y2)

if(y2-y1)

m=(x2-x1)/(y2-y1);

else

m=100000;

if(y1 >= ymin && y2 >= ymin)

arr[k]=x2;

arr[k+1]=y2;

k+=2;

}
if(y1 < ymin && y2 >= ymin)

arr[k]=x1+m*(ymin-y1);

arr[k+1]=ymin;

arr[k+2]=x2;

arr[k+3]=y2;

k+=4;

if(y1 >= ymin && y2 < ymin)

arr[k]=x1+m*(ymin-y1);

arr[k+1]=ymin;

k+=2;

int main()

int gdriver=DETECT,gmode,n,poly[20];

float xi,yi,xf,yf,polyy[20];

// clrscr();

cout<<"Coordinates of rectangular clip window :\nxmin,ymin :";

cin>>xmin>>ymin;

cout<<"xmax,ymax :";

cin>>xmax>>ymax;

cout<<"\n\nPolygon to be clipped :\nNumber of sides :";

cin>>n;

cout<<"Enter the coordinates :";

int i;

for( i=0;i < 2*n;i++)


cin>>polyy[i];

polyy[i]=polyy[0];

polyy[i+1]=polyy[1];

for(i=0;i < 2*n+2;i++)

poly[i]=round(polyy[i]);

initgraph(&gdriver,&gmode,"C:\\TC\\BGI");

setcolor(RED);

rectangle(xmin,ymax,xmax,ymin);

cout<<"\t\tUNCLIPPED POLYGON";

setcolor(WHITE);

fillpoly(n,poly);

getch();

cleardevice();

k=0;

for(i=0;i < 2*n;i+=2)

clipl(polyy[i],polyy[i+1],polyy[i+2],polyy[i+3]);

n=k/2;

for(i=0;i < k;i++)

polyy[i]=arr[i];

polyy[i]=polyy[0];

polyy[i+1]=polyy[1];

k=0;

for(i=0;i < 2*n;i+=2)

clipt(polyy[i],polyy[i+1],polyy[i+2],polyy[i+3]);

n=k/2;

for(i=0;i < k;i++)

polyy[i]=arr[i];

polyy[i]=polyy[0];

polyy[i+1]=polyy[1];
k=0;

for(i=0;i < 2*n;i+=2)

clipr(polyy[i],polyy[i+1],polyy[i+2],polyy[i+3]);

n=k/2;

for(i=0;i < k;i++)

polyy[i]=arr[i];

polyy[i]=polyy[0];

polyy[i+1]=polyy[1];

k=0;

for(i=0;i < 2*n;i+=2)

clipb(polyy[i],polyy[i+1],polyy[i+2],polyy[i+3]);

for(i=0;i < k;i++)

poly[i]=round(arr[i]);

if(k)

fillpoly(k/2,poly);

setcolor(RED);

rectangle(xmin,ymax,xmax,ymin);

cout<<"\tCLIPPED POLYGON";

getch();

closegraph();

Output:
Before:
After:

Findings and Learnings:


1. The algorithm uses and divide and conquer approach.
2. This algorithm does not work if the clip window is not convex.
3. If the polygon is not also convex, there may be some dangling edges.
Experiment-9

Aim:
Write a program to implement Translation, Rotation and Scaling of an object.

Description:
A translation process moves every point a constant distance in a specified
direction. It can be described as a rigid motion. A translation can also be
interpreted as the addition of a constant vector to every point, or as shifting the
origin of the coordinate system.
Suppose, If point P(X, Y) is to be translated by amount Dx and Dy to a new location
P’(X’, Y’) then new coordinates can be obtained by adding Dx to X and Dy to Y as:
X’ = Dx + X
Y’ = Dy + Y
Or
P’ = T + P
where P’ = [X’,Y’] ; T = [Dx,Dy]; P = [X,Y];
Algorithm:

1. Start
2. Initialize the graphics mode.
3. Construct a 2D object
4. Translation
a. Get the translation value tx, ty
b. Move the 2d object with tx, ty (x’=x+tx,y’=y+ty)
c. Plot (x’,y’)
Code:
#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<dos.h>

void translateRectangle ( int P[][2], int T[])


{
/* init graph and rectangle() are used for
representing rectangle through graphical functions */
int gd = DETECT, gm, errorcode;
initgraph (&gd, &gm, "c://bgi");
setcolor (2);
// rectangle (Xmin, Ymin, Xmax, Ymax)
// original rectangle
rectangle (P[0][0], P[0][1], P[1][0], P[1][1]);

// calculating translated coordinates


P[0][0] = P[0][0] + T[0];
P[0][1] = P[0][1] + T[1];
P[1][0] = P[1][0] + T[0];
P[1][1] = P[1][1] + T[1];

translated rectangle (Xmin, Ymin, Xmax, Ymax)


setcolor(3);
rectangle (P[0][0], P[0][1], P[1][0], P[1][1]);
closegraph();
getch();
}
int main()
{
// Xmin, Ymin, Xmax, Ymax as rectangle
// coordinates of top left and bottom right points
int P[2][2] = {100, 100, 200, 200};
int T[] = {50, 70}; // translation factor
translateRectangle (P, T);
return 0;
}

Output:

Findings and Learnings:


Translation can be achieved by any given factor by summation of the translation
factor to the original coordinates of the object.
Advantages:
● Useful for coordinate transformations.
● Used extensively while performing 2D and 3D transformations.
● Change of Basis.
Rotation

Description:
In rotation, we rotate the object at particular angle θ (theta) from its origin. From
the following figure, we can see that the point P(X, Y) is located at angle φ from the
horizontal X coordinate with distance r from the origin.

Let us suppose you want to rotate it at the angle θ. After rotating it to a new
location, you will get a new point P’ (X’, Y’).

Using standard trigonometric the original coordinate of point P(X, Y) can be


represented as −
X=rcosϕ......(1)
Y=rsinϕ......(2)
Same way we can represent the point P’ (X’, Y’) as −
x′=rcos(ϕ+θ)=rcosϕcosθ−rsinϕsinθ.......(3)
y′=rsin(ϕ+θ)=rcosϕsinθ+rsinϕcosθ.......(4)

Substituting equation (1) & (2) in (3) & (4) respectively, we will get
x′=xcosθ−ysinθ
y′=xsinθ+ycosθ
Representing the above equation in matrix form we have the Roation matrix R as,

Algorithm:
1. Start

2. Initialize the graphics mode.

3. Construct a 2D object (use DrawLine()) e.g. (x , y))

4. Rotation

a. Get the Rotation angle


b. Rotate the object by the angle ф

x’=x cos ф - y sin ф


y’=x sin ф - y cosф
c. Plot (x’,y’)
Code:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<graphics.h>
#include<math.h>

#define ROUND(a) ((int)(a+0.5))

void ddaline(int x1, int y1, int x2, int y2,int color)

{ float xsteps, ysteps, x=x1, y=y1;

int dx = x2-x1;
int dy = y2-y1;
int steps,k=1;

if(abs(dx)>=abs(dy))

steps=abs(dx);
else steps=abs(dy);

xsteps= dx/(float)steps;
ysteps= dy/(float)steps;

putpixel(ROUND(x),ROUND(y),color);

while(k<=steps)
{

x+=xsteps;
y+=ysteps;
putpixel(ROUND(x), ROUND(y),color);
k++;
}
}

void rotate(int x1, int y1, int x2, int y2, float theta)

{ int xtmp, ytmp;


float th = (3.14 * theta )/180;
xtmp = x1 + ROUND ((x2-x1)*cos(th) - (y2-y1)*sin(th));

ytmp = y1 + ROUND ((x2-x1)*sin(th) + (y2-y1)*cos(th));


ddaline(x1,y1,x2,y2,10);
ddaline(x1,y1,xtmp,ytmp,12);
}

int main()
{
int x1, x2, y1, y2;
float theta;

int gdriver = DETECT, gmode, errorcode;


initgraph(&gdriver, &gmode, "C:\\TURBOC3\\BGI");
errorcode = graphresult();

if (errorcode != grOk)
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");

getch();
exit(1);
}

printf("Enter start point\n");


scanf("%d %d", &x1, &y1);
printf("Enter end point\n");
scanf("%d %d", &x2, &y2);
printf("Enter value of angle to rotate line about starting point\n");
scanf("%f", &theta);

rotate(x1, y1, x2, y2, theta);

getch();
closegraph();
return 0;
}

OUTPUT:

Findings and Learning:

● A rotation matrix is a matrix that is used to perform a rotation in Euclidean


space. To perform the rotation using a rotation matrix R, the position of
each point must be represented by a column vector v, containing the
coordinates of the point. A rotated vector is obtained by using the matrix
multiplication Rv.
● Rotation of a complete object can viewed as rotation of all its constituent
lines about a fixed point.
● Rotation matrices are square matrices, with real entries. More specifically,
they can be characterized as orthogonal matrices with determinant 1.
● Coordinate rotations are a natural way to express the orientation of a
camera, or the attitude of a spacecraft, relative to a reference axes-set.
These are also used in various image editing software to perform simple
rotation of images.

SCALING

Description:

A scaling can be represented by a scaling matrix. To scale an object by a vector v =


(vx, vy, vz), each point p = (px, py, pz) would need to be multiplied with this
scaling matrix:

As shown below, the multiplication will give the expected result:

Such a scaling changes the diameter of an object by a factor between the scale
factors, the area by a factor between the smallest and the largest product of two
scale factors, and the volume by the product of all three.
The scaling is uniform if and only if the scaling factors are equal (vx = vy = vz). If all
except one of the scale factors are equal to 1, we have directional scaling.
In the case where vx = vy = vz = k, the scaling is also called an enlargement or
dilation by a factor k, increasing the area by a factor of k2 and the volume by a
factor of k3.
A scaling in the most general sense is any affine transformation with a
diagonalizable matrix. It includes the case that the three directions of scaling are
not perpendicular. It includes also the case that one or more scale factors are equal
to zero (projection), and the case of one or more negative scale factors. The latter
corresponds to a combination of scaling proper and a kind of reflection. Along lines
in a particular direction we take the reflection in the point of intersection with a
plane that need not be perpendicular; therefore it is more general than ordinary
reflection in the plane.
If we provide values less than 1 to the scaling factor S, then we can reduce the
size of the object. If we provide values greater than 1, then we can increase the
size of the object.

Algorithm:

1. For each vertex of the algorithm:


a. X = Sx*X
b. Y = Sy*Y
2. Redraw the polygon with new set of vertices.

Code:
#include <stdio.h>
#include <conio.h>
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
#define ROUND(a) ((int)(a+0.5))
void thickline(int X0, int Y0, int X1, int Y1) {
// calculate dx & dy
int dx = X1 - X0;
int dy = Y1 - Y0;

// calculate steps required for generating pixels


int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);

// calculate increment in x & y for each steps


float Xinc = dx / (float) steps;
float Yinc = dy / (float) steps;

// Put pixel for each step


float X = X0;
float Y = Y0;
int i;
for (i = 0; i <= steps; i++) {
putpixel (ROUND(X),ROUND(Y),WHITE);// put pixel at (X,Y)
X += Xinc; // increment in x at each step
Y += Yinc; // increment in y at each step
delay(50); // for visualization of line-
// generation step by step
}
}

void scaling(int *x, int *y, int sx, int sy) {


*x =(*x)*sx;
*y = (*y)*sy;
}
int main() {
int x0 = 50, y0 = 50, x1 = 100, y1 = 100;

int gdriver = DETECT, gmode, errorcode;


initgraph(&gdriver, &gmode, "..\\");
errorcode = graphresult();

if(errorcode != grOk) {
printf("Graphics Error: %s\n",grapherrormsg(errorcode));
printf("Press key to halt");
getch();
exit(1);
}
thickline(x0,y0,x0,y1);
thickline(x0,y0,x1,y0);
thickline(x0,y1,x1,y1);
thickline(x1,y0,x1,y1);
delay(100);
closegraph();
clrscr();
scaling(&x0,&y0,2,2);
scaling(&x0,&y1,2,2);
scaling(&x1,&y0,2,2);
scaling(&x1,&y1,2,2);
gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "..\\");
errorcode = graphresult();

if(errorcode != grOk) {
printf("Graphics Error: %s\n",grapherrormsg(errorcode));
printf("Press key to halt");
getch();
exit(1);
}
thickline(x0,y0,x0,y1);
thickline(x0,y0,x1,y0);
thickline(x0,y1,x1,y1);
thickline(x1,y0,x1,y1);

getch();
closegraph();
return 0;
}

Output:

Before Scaling:
After Scaling:

Findings & Learnings:

In projective geometry, often used in computer graphics, points are represented


using homogeneous coordinates. To scale an object by a vector v = (vx, vy, vz), each
homogeneous coordinate vector p = (px, py, pz, 1) would need to be multiplied with
this projective transformation matrix:
Experiment-10

Aim:
Write a program to implement Liang Barsky Line Clipping algorithm.

Description:
● The Liang–Barsky algorithm uses the parametric equation of a line and inequalities describing the
range of the clipping window to determine the intersections between the line and the clip window.
With these intersections it knows which portion of the line should be drawn.
● This algorithm is significantly more efficient than Cohen–Sutherland.
● The idea of the Liang–Barsky clipping algorithm is to do as much testing as possible before
computing line intersections.

Algorithm:
1. Set tmin=0 and tmax=0
2. Calculate the values of tL, tR, tT, and tB (tvalues).
2.1 if t < tmin or t > tmax ignore it and go to the next edge
2.2 otherwise classify the tvalue as entering or exiting value (using inner product to
classify)
2.3 if t is entering value set tmin = t ;
if t is exiting value set tmax = t
3. If tmin < tmax then draw a line from (x1 + dxtmin, y1 + dytmin) to (x1 + dxtmax, y1 +
dytmax)
4. If the line crosses over the window, you will see (x1 + dxtmin, y1 + dytmin) and (x1 +
dxtmax, y1 + dytmax) are intersection between line and edge.

CODE:

#include<iostream.h>
#include<conio.h>
#include<graphics.h>
void main()
{
int gd = DETECT,gm;
initgraph(&gd,&gm,"C:\\TC\\BGI");
int x1,y1,x2,y2,xmax,xmin,ymax,ymin,xx1,yy1,xx2,yy2,dx,dy,i;
int p[4],q[4];
float t1,t2,t[4];
cout<<"Enter the lower co-ordinates of window";
cin>>xmin>>ymin;
cout<<"Enter the upper co-ordinates of window";
cin>>xmax>>ymax;
setcolor(RED);
rectangle(xmin,ymin,xmax,ymax);
cout<<"Enter x1:";
cin>>x1;
cout<<"Enter y1:";
cin>>y1;
cout<<"Enter x2:";
cin>>x2;
cout<<"Enter y2:";
cin>>y2;
line(x1,y1,x2,y2);
dx=x2-x1;
dy=y2-y1;
p[0]=-dx;
p[1]=dx;
p[2]=-dy;
p[3]=dy;
q[0]=x1-xmin;
q[1]=xmax-x1;
q[2]=y1-ymin;
q[3]=ymax-y1;

for(i=0;i < 4;i++)


{
if(p[i]!=0)
{
t[i]=(float)q[i]/p[i];
}
else
if(p[i]==0 && q[i] < 0)
cout<<"Line completely outside the window";
else
if(p[i]==0 && q[i] >= 0)
cout<<"Line completely inside the window";
}
if (t[0] > t[2]){
t1=t[0];
}
else{
t1=t[2];
}
if (t[1] < t[3]){
t2=t[1];
}
else{
t2=t[3];
}
if (t1 < t2){
xx1=x1+t1*dx;
xx2=x1+t2*dx;
yy1=y1+t1*dy;
yy2=y1+t2*dy;
cout<<"Line after clipping:";
setcolor(WHITE);
line(xx1,yy1,xx2,yy2);
}
else
{
cout<<"Line lies out of the window" }
getch();
}

Result:

Before Clipping:
After clipping:

Findings and Learnings:


1. More efficient than other algorithms as line intersection with boundaries
calculations are reduced.
2. Intersections of line are computed only once.

It can also be extended to 3-Dimensional Clipping. At most 4 parameter values are


computed in Liang Barsky Algorithm and it is a non-iterative algorithm.

You might also like