Unit 1 of 1 · M.Sc IT Sem 3

Unit 1: 2D graphics algorithm implementation

Computer Graphics Laboratory notes · PTU syllabus (PGCA1923)

10 min read11 topics10 exam questions
On this page
  1. Unit summary
  2. Setting up graphics.h
  3. Pixels, simple shapes and text formatting
  4. DDA line algorithm
  5. Bresenham's line algorithm and comparison with DDA
  6. Moving wheel using midpoint circle and DDA
  7. Ellipse using the midpoint algorithm
  8. 2D transformations on user input
  9. Boundary fill algorithm
  10. Scan-line polygon fill algorithm
  11. Line clipping: Cohen–Sutherland
  12. Sutherland–Hodgman polygon clipping
  13. Key terms
  14. Quick revision
  15. Important questions

Unit summary

This lab implements 2D graphics: plotting pixels, drawing lines and circles, formatted text, DDA and Bresenham line algorithms, a moving wheel using midpoint circle and DDA, midpoint ellipses, translation, rotation and scaling from user input, triangle rotation, combined scaling and translation, boundary fill, scan-line polygon fill, line clipping and Sutherland–Hodgman polygon clipping.

After this unit you can

  • Use graphics library functions to draw primitives and text
  • Implement line, circle and ellipse algorithms and simple animation
  • Apply 2D transformations to shapes
  • Implement filling and clipping algorithms

PTU syllabus topics

  • Pixel plotting
  • simple 2D shape drawing (lines, circles)
  • text formatting with graphics functions
  • DDA line-drawing algorithm
  • Bresenham's line algorithm comparison
  • moving wheel via midpoint circle and DDA algorithms
  • ellipse generation via midpoint algorithm
  • 2D transformations (translation, rotation, scaling) on user input
  • triangle rotation
  • combined scaling and translation operations
  • boundary fill algorithm
  • scan-line polygon fill algorithm
  • line clipping algorithms
  • Sutherland-Hodgeman polygon clipping
ProcessMidpoint circle algorithm
  1. 1

    Start at (0, r)

  2. 2

    Decision p = 1 − r

  3. 3

    If p < 0

    Next (x + 1, y); p += 2x + 3

  4. 4

    Else

    Next (x + 1, y − 1); p += 2(x − y) + 5

  5. 5

    Plot all 8 symmetric points

  6. 6

    Repeat while x < y

1

Topic 1

Setting up graphics.h

  • graphics.h is the Borland BGI library used in Turbo C++. On modern systems use WinBGIm with Code::Blocks or Dev-C++ (link libbgi, libgdi32, libcomdlg32, libuuid, libole32, liboleaut32), or a DOS emulator running Turbo C++. Every program starts with initgraph and ends with closegraph.
cpp#include <graphics.h>
#include <conio.h>
int main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, (char*)"");     // "C:\\TURBOC3\\BGI" in Turbo C++
    // drawing code
    getch();
    closegraph();
    return 0;
}
2

Topic 2

Pixels, simple shapes and text formatting

Key termsgraphics.h functions
putpixel(x, y, color)
Plot one pixel
line(x1, y1, x2, y2)
Draw a line
rectangle(left, top, right, bottom)
Draw a rectangle
circle(x, y, r)
Draw a circle
arc(x, y, start, end, r)
Draw an arc between angles
ellipse(x, y, start, end, xr, yr)
Draw an ellipse or elliptical arc
setcolor(c), setfillstyle(pattern, c)
Set drawing and fill colours
floodfill(x, y, border)
Fill an area bounded by the border colour
outtextxy(x, y, text)
Write text
cleardevice(), delay(ms)
Clear screen; pause
cppsetcolor(YELLOW);
circle(150, 150, 60);
setfillstyle(SOLID_FILL, BLUE);
floodfill(150, 150, YELLOW);            // fill inside the yellow circle
setcolor(WHITE);
rectangle(250, 100, 400, 200);
arc(500, 150, 0, 180, 50);
ellipse(320, 320, 0, 360, 100, 50);
putpixel(320, 320, RED);
outtextxy(260, 400, (char*)"Basic shapes");
cppsettextstyle(TRIPLEX_FONT, HORIZ_DIR, 3);       // font, direction, size
setcolor(LIGHTCYAN);
outtextxy(100, 40, (char*)"Computer Graphics Lab");
settextjustify(CENTER_TEXT, CENTER_TEXT);
settextstyle(SANS_SERIF_FONT, VERT_DIR, 2);
outtextxy(50, 240, (char*)"SBS");
3

Topic 3

DDA line algorithm

cpp#include <cmath>
void ddaLine(int x1, int y1, int x2, int y2) {
    int dx = x2 - x1, dy = y2 - y1;
    int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
    float xinc = dx / (float)steps, yinc = dy / (float)steps;
    float x = x1, y = y1;
    for (int i = 0; i <= steps; i++) {
        putpixel((int)round(x), (int)round(y), GREEN);
        x += xinc; y += yinc;
    }
}
4

Topic 4

Bresenham's line algorithm and comparison with DDA

cppvoid bresLine(int x1, int y1, int x2, int y2) {
    int dx = abs(x2 - x1), dy = abs(y2 - y1);
    int sx = x1 < x2 ? 1 : -1, sy = y1 < y2 ? 1 : -1;
    int err = dx - dy;
    while (true) {
        putpixel(x1, y1, CYAN);
        if (x1 == x2 && y1 == y2) break;
        int e2 = 2 * err;
        if (e2 > -dy) { err -= dy; x1 += sx; }
        if (e2 <  dx) { err += dx; y1 += sy; }
    }
}
ComparisonDDA and Bresenham
DDA
Bresenham

Arithmetic

Floating-point additions and rounding

Integer additions and subtractions only

Speed

Slower

Faster

Accuracy

Rounding errors accumulate on long lines

Exact choice of nearest pixel

Hardware

Needs floating-point support

Suits simple hardware

5

Topic 5

Moving wheel using midpoint circle and DDA

cpp#include <graphics.h>
#include <cmath>
void midCircle(int xc, int yc, int r, int c) {
    int x = 0, y = r, p = 1 - r;
    while (x <= y) {
        int pts[8][2] = {{x,y},{y,x},{-x,y},{-y,x},{x,-y},{y,-x},{-x,-y},{-y,-x}};
        for (auto &q : pts) putpixel(xc + q[0], yc + q[1], c);
        x++;
        if (p < 0) p += 2 * x + 1; else { y--; p += 2 * (x - y) + 1; }
    }
}
void ddaLine(int x1, int y1, int x2, int y2, int c) {
    int steps = std::max(abs(x2 - x1), abs(y2 - y1));
    float x = x1, y = y1, dx = (x2 - x1) / (float)steps, dy = (y2 - y1) / (float)steps;
    for (int i = 0; i <= steps; i++) { putpixel(round(x), round(y), c); x += dx; y += dy; }
}
int main() {
    int gd = DETECT, gm; initgraph(&gd, &gm, (char*)"");
    int r = 40, y = 300;
    for (int xc = 50; xc < 600; xc += 4) {
        double a = (xc - 50) / (double)r;               // angle rolled = distance / radius
        cleardevice();
        line(0, y + r, getmaxx(), y + r);               // ground
        midCircle(xc, y, r, WHITE);
        for (int k = 0; k < 4; k++) {                   // four spokes
            double t = a + k * M_PI / 4;
            ddaLine(xc - r * cos(t), y - r * sin(t), xc + r * cos(t), y + r * sin(t), YELLOW);
        }
        delay(30);
    }
    closegraph();
}
6

Topic 6

Ellipse using the midpoint algorithm

cppvoid plot4(int xc, int yc, int x, int y, int c) {
    putpixel(xc + x, yc + y, c); putpixel(xc - x, yc + y, c);
    putpixel(xc + x, yc - y, c); putpixel(xc - x, yc - y, c);
}
void midEllipse(int xc, int yc, long rx, long ry) {
    long x = 0, y = ry;
    double p1 = ry * ry - rx * rx * ry + 0.25 * rx * rx;
    while (2 * ry * ry * x < 2 * rx * rx * y) {          // region 1
        plot4(xc, yc, x, y, LIGHTGREEN);
        x++;
        if (p1 < 0) p1 += 2 * ry * ry * x + ry * ry;
        else { y--; p1 += 2 * ry * ry * x - 2 * rx * rx * y + ry * ry; }
    }
    double p2 = ry * ry * (x + 0.5) * (x + 0.5) + rx * rx * (y - 1) * (y - 1) - rx * rx * ry * ry;
    while (y >= 0) {                                      // region 2
        plot4(xc, yc, x, y, LIGHTGREEN);
        y--;
        if (p2 > 0) p2 += rx * rx - 2 * rx * rx * y;
        else { x++; p2 += 2 * ry * ry * x - 2 * rx * rx * y + rx * rx; }
    }
}
7

Topic 7

2D transformations on user input

cpp#include <graphics.h>
#include <iostream>
#include <cmath>
using namespace std;
int main() {
    int gd = DETECT, gm; initgraph(&gd, &gm, (char*)"");
    int x[3] = {200, 300, 250}, y[3] = {200, 200, 120};    // triangle
    auto draw = [&](int c) { setcolor(c);
        for (int i = 0; i < 3; i++) line(x[i], y[i], x[(i + 1) % 3], y[(i + 1) % 3]); };
    draw(WHITE);
    int ch; cout << "1 Translate 2 Rotate 3 Scale: "; cin >> ch;
    if (ch == 1) { int tx, ty; cin >> tx >> ty; for (int i = 0; i < 3; i++) { x[i] += tx; y[i] += ty; } }
    else if (ch == 2) {                                    // rotate about the first vertex
        double deg; cin >> deg; double t = deg * M_PI / 180;
        int xr = x[0], yr = y[0];
        for (int i = 0; i < 3; i++) {
            int dx = x[i] - xr, dy = y[i] - yr;
            x[i] = xr + round(dx * cos(t) - dy * sin(t));
            y[i] = yr + round(dx * sin(t) + dy * cos(t));
        }
    } else {                                               // scale about the first vertex
        double sx, sy; cin >> sx >> sy;
        for (int i = 0; i < 3; i++) { x[i] = x[0] + round((x[i] - x[0]) * sx); y[i] = y[0] + round((y[i] - y[0]) * sy); }
    }
    draw(YELLOW);
    getch(); closegraph();
}
  • Combined scaling and translation: apply scaling about the origin and then translation (or multiply the 3 × 3 matrices T × S and apply the product to each vertex); compare the result with the reverse order to show that order matters.
8

Topic 8

Boundary fill algorithm

cppvoid boundaryFill4(int x, int y, int fill, int boundary) {
    int c = getpixel(x, y);
    if (c != boundary && c != fill) {
        putpixel(x, y, fill);
        boundaryFill4(x + 1, y, fill, boundary); boundaryFill4(x - 1, y, fill, boundary);
        boundaryFill4(x, y + 1, fill, boundary); boundaryFill4(x, y - 1, fill, boundary);
    }
}
/* usage: setcolor(RED); rectangle(100,100,180,160); boundaryFill4(140,130,GREEN,RED); */
9

Topic 9

Scan-line polygon fill algorithm

cpp#include <algorithm>
#include <vector>
void scanFill(int n, int px[], int py[], int color) {
    int ymin = *std::min_element(py, py + n), ymax = *std::max_element(py, py + n);
    for (int y = ymin; y <= ymax; y++) {
        std::vector<int> xs;
        for (int i = 0; i < n; i++) {
            int x1 = px[i], y1 = py[i], x2 = px[(i + 1) % n], y2 = py[(i + 1) % n];
            if (y1 == y2) continue;                               // skip horizontal edges
            if ((y >= std::min(y1, y2)) && (y < std::max(y1, y2)))  // half-open rule avoids double vertices
                xs.push_back(x1 + (y - y1) * (x2 - x1) / (y2 - y1));
        }
        std::sort(xs.begin(), xs.end());
        setcolor(color);
        for (size_t k = 0; k + 1 < xs.size(); k += 2) line(xs[k], y, xs[k + 1], y);   // fill between pairs
    }
}
10

Topic 10

Line clipping: Cohen–Sutherland

cpp// Cohen–Sutherland line clipping
const int INSIDE = 0, LEFT = 1, RIGHT = 2, BOTTOM = 4, TOP = 8;
int xmin = 150, ymin = 150, xmax = 450, ymax = 350;      // clipping window

int code(int x, int y) {
    int c = INSIDE;
    if (x < xmin) c |= LEFT;   else if (x > xmax) c |= RIGHT;
    if (y < ymin) c |= BOTTOM; else if (y > ymax) c |= TOP;
    return c;
}
void cohenSutherland(int x1, int y1, int x2, int y2) {
    int c1 = code(x1, y1), c2 = code(x2, y2);
    bool accept = false;
    while (true) {
        if (!(c1 | c2)) { accept = true; break; }        // both inside
        if (c1 & c2) break;                               // both outside same side
        int out = c1 ? c1 : c2; double x, y;
        if (out & TOP)         { x = x1 + (x2 - x1) * (ymax - y1) / (double)(y2 - y1); y = ymax; }
        else if (out & BOTTOM) { x = x1 + (x2 - x1) * (ymin - y1) / (double)(y2 - y1); y = ymin; }
        else if (out & RIGHT)  { y = y1 + (y2 - y1) * (xmax - x1) / (double)(x2 - x1); x = xmax; }
        else                   { y = y1 + (y2 - y1) * (xmin - x1) / (double)(x2 - x1); x = xmin; }
        if (out == c1) { x1 = (int)x; y1 = (int)y; c1 = code(x1, y1); }
        else           { x2 = (int)x; y2 = (int)y; c2 = code(x2, y2); }
    }
    rectangle(xmin, ymin, xmax, ymax);
    if (accept) { setcolor(YELLOW); line(x1, y1, x2, y2); }
}
  • Windowing: map a world-coordinate window to a screen viewport with xv = xvmin + (xw − xwmin) × sx and yv = yvmin + (yw − ywmin) × sy; draw the original and the mapped figure side by side to check the result.
11

Topic 11

Sutherland–Hodgman polygon clipping

cpp#include <vector>
struct P { double x, y; };
// clip polygon against one edge: inside(p) tests the side, cut(a, b) returns the intersection
template <class In, class Cut>
std::vector<P> clipEdge(const std::vector<P>& poly, In inside, Cut cut) {
    std::vector<P> out;
    for (size_t i = 0; i < poly.size(); i++) {
        P s = poly[i], p = poly[(i + 1) % poly.size()];
        bool sIn = inside(s), pIn = inside(p);
        if (sIn && pIn) out.push_back(p);                      // in → in: output P
        else if (sIn && !pIn) out.push_back(cut(s, p));        // in → out: output I
        else if (!sIn && pIn) { out.push_back(cut(s, p)); out.push_back(p); }   // out → in: I and P
    }                                                          // out → out: nothing
    return out;
}
std::vector<P> clip(std::vector<P> poly, double xmin, double ymin, double xmax, double ymax) {
    auto atX = [](P a, P b, double x) { return P{x, a.y + (b.y - a.y) * (x - a.x) / (b.x - a.x)}; };
    auto atY = [](P a, P b, double y) { return P{a.x + (b.x - a.x) * (y - a.y) / (b.y - a.y), y}; };
    poly = clipEdge(poly, [&](P p){ return p.x >= xmin; }, [&](P a, P b){ return atX(a, b, xmin); });
    poly = clipEdge(poly, [&](P p){ return p.x <= xmax; }, [&](P a, P b){ return atX(a, b, xmax); });
    poly = clipEdge(poly, [&](P p){ return p.y >= ymin; }, [&](P a, P b){ return atY(a, b, ymin); });
    poly = clipEdge(poly, [&](P p){ return p.y <= ymax; }, [&](P a, P b){ return atY(a, b, ymax); });
    return poly;
}
  • Draw the window, the original polygon in one colour and the clipped polygon in another to check the output.

Key terms

putpixel
Function lighting a single pixel
Midpoint circle algorithm
Integer circle algorithm using a decision parameter
Composite transformation
Combined matrix of several transformations
Scan-line fill
Filling between edge intersections on each scan line
Sutherland–Hodgman
Polygon clipping against one window edge at a time

Quick revision

  • initgraph, putpixel, line, circle, settextstyle, outtextxy.
  • DDA vs Bresenham; moving wheel with midpoint circle and DDA spokes.
  • Midpoint ellipse; translation, rotation, scaling on input; rotation about a vertex; T × S vs S × T.
  • Boundary fill; scan-line fill with sorted intersections.
  • Cohen–Sutherland line clipping; Sutherland–Hodgman polygon clipping.

Important exam questions

Practice questions written to the PTU exam pattern for this unit's syllabus: short answers (Section A style) and long answers (Sections B and C style).

Short-answer questions

  1. Q1.Which function changes the font in graphics.h?
  2. Q2.Why is Bresenham's algorithm faster than DDA?
  3. Q3.How is a wheel made to appear to roll?
  4. Q4.How do you rotate a triangle about one of its vertices?
  5. Q5.Why are intersections sorted in scan-line fill?
  6. Q6.What are the four cases in Sutherland–Hodgman clipping?

Long-answer questions

  1. Q1.Write programs to draw lines using DDA and Bresenham and compare them.
  2. Q2.Write a program to animate a moving wheel.
  3. Q3.Write a program to translate, rotate and scale a triangle.
  4. Q4.Write programs for scan-line fill and Sutherland–Hodgman clipping.

Stuck on this unit?

Message SBS on WhatsApp for help with Computer Graphics Laboratory, or to ask about studying M.Sc IT at Synetic.

WhatsApp us