0% found this document useful (0 votes)
31 views25 pages

Lab File Rudra

The document is a lab file for a Computer Graphics course, detailing various experiments and algorithms such as DDA Line, Bresenham Line, Midpoint Circle, and others. Each experiment includes a theoretical explanation, code implementation, and learning outcomes. The focus is on fundamental graphics algorithms and their applications in rendering shapes and filling areas.

Uploaded by

rudra chauhan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views25 pages

Lab File Rudra

The document is a lab file for a Computer Graphics course, detailing various experiments and algorithms such as DDA Line, Bresenham Line, Midpoint Circle, and others. Each experiment includes a theoretical explanation, code implementation, and learning outcomes. The focus is on fundamental graphics algorithms and their applications in rendering shapes and filling areas.

Uploaded by

rudra chauhan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

DEPARTMENT OF CSE

Computer Graphics Lab

CO 313- Computer Graphics

LAB FILE

SUBMITTED TO: - SUBMITTED BY: -


Mrs.DEEPAKSHI DABAS RUDRA CHAUHAN
2K22/CO/384
(E5 Sec-2 G3)
Computer Graphics Lab Experiments Index

S No. Experiment Name Date Signature

1 DDA Line Algorithm

2 Bresenham Line Algorithm


3 Midpoint Circle Algorithm
4 Midpoint Ellipse
5 Algorithm
Flood fill algorithm
6 Boundary fill algorithm
7 2D Translatoin
8 2D Scaling
9 2D Rotation
10 Cohen - Sutherland Line
Clipping Algorithm
11 Liang Barsky line clipping
algorithm
Experiment 1 : DDA Line Algorithm
Theory:
The Digital Differential Analyzer (DDA) line algorithm incrementally plots points between
the start and end coordinates by calculating successive pixel positions. It provides a
straightforward way to render lines but can be computationally slower due to oating-
point operations.

Code:
#include <iostream>
using namespace std;
vector<pair<int, int>> ddaLine(int x1, int y1, int x2, int y2) {
vector<pair<int, int>> points;
int dx = x2 - x1,dy = y2 - y1,steps = max(abs(dx), abs(dy));
oat xIncrement = dx / ( oat)steps, yIncrement = dy / ( oat)steps;
oat x = x1, y = y1;
points.push_back({round(x), round(y)});
for (int i = 0; i < steps; i++) {
x += xIncrement; y += yIncrement;
points.push_back({round(x), round(y)});
}
return points;
}

int main() {
int x1, y1, x2, y2;
cin >> x1 >> y1; cin >> x2 >> y2;
vector<pair<int, int>> linePoints = ddaLine(x1, y1, x2, y2);
for (const auto &point : linePoints) {
cout << "(" << point. rst << ", " << point.second << ")\n";
}

return 0;
}

Output:
fl
fl
fi
fl
fl
fl
Learning: We learnt about the basics of graphics.h library,
initializing a graph, putting a pixel, and closing. Wealso applied
DDA algorithm to create a line between 2 coordinates
Experiment 2: Bresenham Line Algorithm

Theory:
Bresenham's line algorithm ef ciently generates points of a line between two given
endpoints using only integer calculations. It is optimal for digital displays as it minimizes
the amount of computation and avoids oating-point arithmetic.

Code:
#include <iostream>
#include <vector>
using namespace std;

vector<pair<int, int>> bresenhamLine(int x1, int y1, int x2, int y2) {
vector<pair<int, int>> points;
int dx = abs(x2 - x1), dy = abs(y2 - y1);
int sx = (x1 < x2) ? 1 : -1;
int sy = (y1 < y2) ? 1 : -1;
bool steep = dy > dx;
if (steep) swap(dx, dy);
int err = 2 * dy – dx;
for (int i = 0; i <= dx; i++) {
points.push_back({x1, y1});
if (err > 0) {
if (steep) x1 += sx;
else y1 += sy;
err -= 2 * dx;
}
if (steep) y1 += sy;
else x1 += sx;
err += 2 * dy; }
return points;
}

int main() {
int x1, y1, x2, y2;
cout << "Enter the starting point (x1, y1): ";
cin >> x1 >> y1;
cout << "Enter the ending point (x2, y2): ";
fi
fl
cin >> x2 >> y2;
vector<pair<int, int>> linePoints = bresenhamLine(x1, y1, x2, y2);
cout << "The points on the line are:\n";
for (const auto &point : linePoints) {
cout << "(" << point. rst << ", " << point.second << ")\n";
}
return 0;
}

OUTPUT:

Learning: We learnt about the basics of graphics.h library, initializing a graph,

putting a pixel, and closing. Wealso applied DDA algorithm to create a line between 2
coordinates

Experiment 3: Midpoint Circle Algorithm


Theory:
fi
The midpoint circle algorithm determines pixel points needed to draw a circle by
calculating decision parameters. Using symmetry and incremental calculations, it
ef ciently renders a circle without oating-point operations.

Code:
#include <iostream>
#include <vector>
using namespace std
vector<pair<int, int>> midpointCircle(int xc, int yc, int r) {
vector<pair<int, int>> points;
int x = r, y = 0;
int p = 1 - r;
points.push_back({xc + x, yc + y});
if (r > 0) {
points.push_back({xc - x, yc + y});
points.push_back({xc + y, yc + x});
points.push_back({xc + y, yc - x});
}
while (x > y) {
y++;
if (p <= 0)
p += 2 * y + 1;
else {
x--;
p += 2 * y - 2 * x + 1;
}
if (x < y) break;
points.push_back({xc + x, yc + y});
points.push_back({xc - x, yc + y});
points.push_back({xc + x, yc - y});
points.push_back({xc - x, yc - y});
if (x != y) {
points.push_back({xc + y, yc + x});
points.push_back({xc - y, yc + x});
points.push_back({xc + y, yc - x});
points.push_back({xc - y, yc - x});
}
}
return points;
}
fi
fl
Output:

Learning: We learnt about the 8-way symmetry property of circle and used it to

plot the 7 other pointscorresponding to one point in order to draw a full circle. We learnt
about the mid-point circlealgorithm.

Experiment 4: Midpoint Ellipse Algorithm


Theory:
This algorithm generates points on an ellipse by calculating midpoints and leveraging
ellipse symmetry, allowing for accurate rendering with incremental, integer-based
calculations.
Code:
#include <iostream>
#include <vector>

using namespace std;

vector<pair<int, int>> midpointEllipse(int xc, int yc, int rx, int ry) {
vector<pair<int, int>> points;
int x = 0, y = ry;
int rxSq = rx * rx, rySq = ry * ry;
int twoRxSq = 2 * rxSq, twoRySq = 2 * rySq;
int px = 0, py = twoRxSq * y;
int p1 = (rySq - (rxSq * ry) + (0.25 * rxSq));

while (px < py) {


points.push_back({xc + x, yc + y});
points.push_back({xc - x, yc + y});
points.push_back({xc + x, yc - y});
points.push_back({xc - x, yc - y});
x++;
px += twoRySq;
if (p1 < 0) p1 += rySq + px;
else {
y--;
py -= twoRxSq;
p1 += rySq + px - py;
}
}

int p2 = (rySq * (x + 0.5) * (x + 0.5) + rxSq * (y - 1) * (y - 1) - rxSq * rySq);


while (y >= 0) {
points.push_back({xc + x, yc + y});
points.push_back({xc - x, yc + y});
points.push_back({xc + x, yc - y});
points.push_back({xc - x, yc - y});
y--;
py -= twoRxSq;
if (p2 > 0) p2 += rxSq - py;
else {
x++;
px += twoRySq;
p2 += rxSq - py + px;
}
}

return points;
}

int main() {
int xc, yc, rx, ry;
cout << "Enter the center of the ellipse (xc, yc): ";
cin >> xc >> yc;
cout << "Enter the radius along x-axis (rx) and y-axis (ry): ";
cin >> rx >> ry;

vector<pair<int, int>> ellipsePoints = midpointEllipse(xc, yc, rx, ry);

cout << "The points on the ellipse are:\n";


for (const auto &point : ellipsePoints) {
cout << "(" << point. rst << ", " << point.second << ")\n";
}

return 0;
}
Output:
fi
Learning: We learnt about the 4-way symmetry property of ellipse and used it to

plot the 3 other pointscorresponding to one point in order to draw a full ellipse. We
learnt about the mid-point ellipsealgorithm

Experiment 5: Flood ll algorithm


fi
Theory:
Flood ll is a recursive algorithm used to ll connected regions with a speci c color,
beginning from a starting pixel and expanding in all directions until boundaries are
reached.

Code:
#include <iostream>
#include <vector>

using namespace std;


void oodFill(vector<vector<int>>& screen, int x, int y, int newColor, int originalColor) {
if (x < 0 || x >= screen.size() || y < 0 || y >= screen[0].size()) return;
if (screen[x][y] != originalColor || screen[x][y] == newColor) return;
screen[x][y] = newColor;
oodFill(screen, x + 1, y, newColor, originalColor);
oodFill(screen, x - 1, y, newColor, originalColor);
oodFill(screen, x, y + 1, newColor, originalColor);
oodFill(screen, x, y - 1, newColor, originalColor);
}
int main() {
int rows, cols, x, y, newColor;
cout << "Enter the dimensions of the screen (rows and cols): ";
cin >> rows >> cols;
vector<vector<int>> screen(rows, vector<int>(cols));
cout << "Enter the screen pixels:\n";
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cin >> screen[i][j];
}
}
cout << "Enter the start point (x, y): ";
cin >> x >> y;
cout << "Enter the new color: ";
cin >> newColor;
int originalColor = screen[x][y];
oodFill(screen, x, y, newColor, originalColor);
cout << "The screen after ood ll:\n";
for (const auto& row : screen) {
for (int pixel : row) {
fl
fl
fl
fl
fl
fl
fi
fl
fi
fi
fi
cout << pixel << " ";
}
cout << "\n";
}
return 0;
}
Output:

Learning: We can modify ndFill() method to reduce storage requirements of the


stack by lling horizontal pixel spans,i.e., we stack only beginning positions for those
pixel spans having oldcolour .In this modi ed version, startingat the rst position of each
span, the pixel values are replaced until a value other than oldcolour isencountered. We
can also show an area bordered by several different color regions too
Experiment 6: Boundary ll algorithm
Theory:

Boundary ll is similar to ood ll but speci cally stops at a prede ned boundary color,
lling the area within this outline from the starting point and adhering to boundary
constraints.
Code:

#include <iostream>
fi
fi
fi
fl
fi
fi
fi
fi
fi
fi
fi
#include <vector>

using namespace std;


void boundaryFill(vector<vector<int>>& screen, int x, int y, int llColor, int
boundaryColor) {
if (x < 0 || x >= screen.size() || y < 0 || y >= screen[0].size()) return;
if (screen[x][y] == boundaryColor || screen[x][y] == llColor) return;
screen[x][y] = llColor;
boundaryFill(screen, x + 1, y, llColor, boundaryColor);
boundaryFill(screen, x - 1, y, llColor, boundaryColor);
boundaryFill(screen, x, y + 1, llColor, boundaryColor);
boundaryFill(screen, x, y - 1, llColor, boundaryColor);
}
int main() {
int rows, cols, x, y, llColor, boundaryColor;
cout << "Enter the dimensions of the screen (rows and cols): ";
cin >> rows >> cols;
vector<vector<int>> screen(rows, vector<int>(cols));
cout << "Enter the screen pixels:\n";
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cin >> screen[i][j];
}
}
cout << "Enter the start point (x, y): ";
cin >> x >> y;
cout << "Enter the ll color: ";
cin >> llColor;
cout << "Enter the boundary color: ";
cin >> boundaryColor;
boundaryFill(screen, x, y, llColor, boundaryColor);
cout << "The screen after boundary ll:\n";
for (const auto& row : screen) {
for (int pixel : row) {
cout << pixel << " ";
}
cout << "\n";
}
return 0;
}
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
Output:

Learning:
1. Boundary Fill is used for the coloring gures in computer graphics. Here, area
gets coloredwith pixels of a chosen color as boundary this giving the technique
its name
2. Boundary ll lls the chosen area with a color until the given colored
boundary is found.

Experiment 7 : 2D Translation

Theory:

Translation in 2D space is the process of moving an object or a point from one position
to another by adding a constant offset along each axis. Unlike rotation and scaling,
translation does not alter the shape or size of the object.

Mathematics of 2D Translation:

● Let (x,y)(x, y)(x,y) be the initial coordinates of a point.


● To translate this point, we add translation values txtxtx and tytyty for the x and y
directions, respectively.
x′=x+txx' = x + txx′=x+tx y′=y+tyy' = y + tyy′=y+ty
fi
fi
fi
Code:
#include <iostream>

void translatePoint( oat x, oat y, oat tx, oat ty) {


oat translatedX = x + tx;
oat translatedY = y + ty;

std::cout << "Translated Point: (" << translatedX << ", " << translatedY << ")\n";
}

int main() {
oat x, y, tx, ty;
std::cout << "Enter the point (x, y): ";
std::cin >> x >> y;
std::cout << "Enter the translation values (tx, ty): ";
std::cin >> tx >> ty;

translatePoint(x, y, tx, ty);


return 0;
}

Output:
fl
fl
fl
fl
fl
fl
fl
Learning:
Translation can be achieved by any given factor by summation of the translation factor
to the originalcoordinates of the object

Experiment 8: 2D Scaling
Theory:
The elliptical arc algorithm calculates pixel points for a speci c segment of an ellipse,
constrained by de ned start and end angles. It utilizes the symmetry of the ellipse and
ef cient point calculations to render arcs precisely.

Code:
#include <iostream>
void scalePoint( oat x, oat y, oat sx, oat sy) {
oat scaledX = x * sx;
oat scaledY = y * sy;
std::cout << "Scaled Point: (" << scaledX << ", " << scaledY << ")\n";
}
int main() {
oat x, y, sx, sy;
std::cout << "Enter the point (x, y): ";
std::cin >> x >> y;
std::cout << "Enter the scaling factors (sx, sy): ";
std::cin >> sx >> sy;
fi
fl
fl
fl
fl
fi
fl
fl
fl
fi
scalePoint(x, y, sx, sy);
return 0;
}
Output:

Learning: 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 9: 2D Rotation

Theory:
The circular arc algorithm calculates the points of an arc segment of a circle by de ning
start and end angles. It applies midpoint or other ef cient methods to limit the arc within
speci c boundaries.

Code:
#include <iostream>
#include <cmath>
#de ne PI 3.14159265

void rotatePoint( oat x, oat y, oat angle) {


oat radians = angle * PI / 180.0;
oat rotatedX = x * cos(radians) - y * sin(radians);
oat rotatedY = x * sin(radians) + y * cos(radians);

std::cout << "Rotated Point: (" << rotatedX << ", " << rotatedY << ")\n";
}

int main() {
oat x, y, angle;
fl
fl
fl
fl
fi
fi
fl
fl
fl
fi
fi
std::cout << "Enter the point (x, y): ";
std::cin >> x >> y;
std::cout << "Enter the angle of rotation: ";
std::cin >> angle;
rotatePoint(x, y, angle);
return 0;
}

Output:

Learning:
●.A rotation matrix is a matrix that is used to perform a rotation in Euclidean space. To
perform therotation using a rotation matrix
R the position of each point must be represented by a column vector containing the
coordinates of the point. A rotated vector is obtained by using the matrixmultiplication.

●Rotation of a complete object can viewed as rotation of all its constituent lines about a
xed point
.
●Rotation matrices are square matrices, with real entries. More speci cally, they can be
characterized asorthogonal matrices with determinant 1.
fi
fi
Experiment 10: Cohen - Sutherland Line Clipping
Algorithm

Theory:
Cohen-Sutherland is a line clipping algorithm that divides space into regions and clips
lines against a de ned rectangular boundary. It assigns region codes to ef ciently
handle lines inside, outside, or partially within the clipping region.
Code:
#include <iostream>
#include <vector>
using namespace std;
#de ne INSIDE 0
#de ne LEFT 1
#de ne RIGHT 2
#de ne BOTTOM 4
#de ne TOP 8
struct Point {
int x, y;
};
int computeCode(int x, int y, int xMin, int yMin, int xMax, int yMax) {
int code = INSIDE;
if (x < xMin) code |= LEFT;
else if (x > xMax) code |= RIGHT;
if (y < yMin) code |= BOTTOM;
else if (y > yMax) code |= TOP;
return code;
}
void cohenSutherland(Point p1, Point p2, int xMin, int yMin, int xMax, int yMax) {
fi
fi
fi
fi
fi
fi
fi
int code1 = computeCode(p1.x, p1.y, xMin, yMin, xMax, yMax);
int code2 = computeCode(p2.x, p2.y, xMin, yMin, xMax, yMax);
bool accept = false;
while (true) {
if ((code1 | code2) == 0) {
accept = true;
break;
} else if (code1 & code2) {
break;
} else {
int codeOut;
if (code1 != 0) codeOut = code1;
else codeOut = code2;
int x, y;
if (codeOut & TOP) {
x = p1.x + (p2.x - p1.x) * (yMax - p1.y) / (p2.y - p1.y);
y = yMax;
} else if (codeOut & BOTTOM) {
x = p1.x + (p2.x - p1.x) * (yMin - p1.y) / (p2.y - p1.y);
y = yMin;
} else if (codeOut & RIGHT) {
y = p1.y + (p2.y - p1.y) * (xMax - p1.x) / (p2.x - p1.x);
x = xMax;
} else if (codeOut & LEFT) {
y = p1.y + (p2.y - p1.y) * (xMin - p1.x) / (p2.x - p1.x);
x = xMin;
}
if (codeOut == code1) {
p1.x = x;
p1.y = y;
code1 = computeCode(p1.x, p1.y, xMin, yMin, xMax, yMax);
} else {
p2.x = x;
p2.y = y;
code2 = computeCode(p2.x, p2.y, xMin, yMin, xMax, yMax);
}}
}
if (accept) {
cout << "Line accepted from (" << p1.x << ", " << p1.y << ") to (" << p2.x << ", " <<
p2.y << ")\n";
} else {
cout << "Line rejected\n"; }
}
int main() {
Point p1, p2;
int xMin, yMin, xMax, yMax;
cout << "Enter the clipping window (xMin, yMin, xMax, yMax): ";
cin >> xMin >> yMin >> xMax >> yMax;
cout << "Enter the line endpoints (p1.x, p1.y, p2.x, p2.y): ";
cin >> p1.x >> p1.y >> p2.x >> p2.y;
cohenSutherland(p1, p2, xMin, yMin, xMax, yMax);
return 0;
}
Output:
Learning: The algorithm divides a two-dimensional space into 9 regions and

then ef ciently determines the lines andportions 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 givenwindow.

Experiment 11: Liang Barsky line clipping algorithm

Theory:
Liang-Barsky's algorithm uses parametric line equations to clip lines more ef ciently
than Cohen-Sutherland, especially for rectangular boundaries. It calculates intersections
based on line parameters, minimizing the number of comparisons.

Code:

#include <iostream>
using namespace std;

struct Point {
oat x, y;
};
void liangBarsky(Point p1, Point p2, oat xMin, oat yMin, oat xMax, oat yMax) {
oat p[] = { p2.x - p1.x, p2.y - p1.y };
oat q[] = { p1.x - xMin, p1.y - yMin };
oat r[] = { xMax - p1.x, yMax - p1.y };
oat s[] = { p1.x - xMax, p1.y - yMax };
oat t0 = 0.0f;
oat t1 = 1.0f;
for (int i = 0; i < 2; i++) {
oat p_i = p[i];
oat q_i = q[i];
oat r_i = r[i];
oat s_i = s[i];
if (p_i == 0) {
fl
fl
fl
fl
fl
fl
fl
fl
fl
fl
fl
fi
fl
fl
fl
fl
fi
if (q_i < 0 || r_i < 0) return;
} else {
oat t = q_i / p_i;
if (p_i < 0) {
if (t > t1) return;
else if (t > t0) t0 = t;
} else {
if (t < t0) return;
else if (t < t1) t1 = t;
}
}
}
if (t0 < t1) {
Point clippedP1 = { p1.x + t0 * p[0], p1.y + t0 * p[1] };
Point clippedP2 = { p1.x + t1 * p[0], p1.y + t1 * p[1] };
cout << "Line accepted from (" << clippedP1.x << ", " << clippedP1.y << ") to (" <<
clippedP2.x << ", " << clippedP2.y << ")\n";
} else {
cout << "Line rejected\n";
}
}
int main() {
Point p1, p2;
oat xMin, yMin, xMax, yMax;
cout << "Enter the clipping window (xMin, yMin, xMax, yMax): ";
cin >> xMin >> yMin >> xMax >> yMax;
cout << "Enter the line endpoints (p1.x, p1.y, p2.x, p2.y): ";
cin >> p1.x >> p1.y >> p2.x >> p2.y;
liangBarsky(p1, p2, xMin, yMin, xMax, yMax);
}
Output:
fl
fl
Learning:

1.More ef cient than other algorithms as line intersection with boundaries calculations
are reduced.
2Intersections of line are computed only once.It can also be extended to 3-Dimensional
Clipping. At most 4 parameter values are computed in Liang BarskyAlgorithm and it is a
non-iterative algorithm.
fi

You might also like