Monday, 28 March 2016

Computer Graphics Hands-On Lab: Mastering Line Drawing Algorithms in C++ - DDA vs. Bresenham

Computer Graphics Hands-On Lab-1 : Mastering Line Drawing Algorithms in C++ - DDA vs. Bresenham

Focus Keyword: Line Drawing Algorithms

Instructor: Dr. Zeeshan Bhatti

Polynomial Method Line Drawing in Computer Graphics | How to Draw Line using DDA algorithm in CG 🎮04

Lab Objectives

Welcome to your first computer graphics lab! This foundational session introduces you to the core problem of raster graphics: how to draw a straight line on a pixel-based display. By the end of this lab, you will:

  • Understand and implement the Digital Differential Analyzer (DDA) line algorithm.

  • Master the highly efficient Bresenham's Line Drawing Algorithm.

  • Learn to create reusable graphics functions.

  • Build complex shapes (rectangles) from primitive lines.

  • Gain practical C++ programming experience with graphical output.


Lab Guidelines & Importance

This is a Lab Project, to be done and submitted by each individual student during the Lab.

  • Individual Work: Each student must complete the tasks individually. Understanding these algorithms is crucial for advanced graphics concepts.

  • Submission: Print your Source Code and get it signed by the lecturer each week.

  • Assessment: Lab projects carry marks that contribute to your final exam. The final Viva Voce will be based on these projects.

  • Final Viva: You MUST bring all completed and signed Lab Project files to your final Viva Voce for marks input.


The Core Programming Tasks

We will use C++ with the Borland Graphics Interface (BGI) for simple graphical output. Ensure your IDE (like Turbo C++, Code::Blocks with WinBGIM) is set up correctly.


Task 1: Implement the DDA Line Drawing Algorithm

The Digital Differential Analyzer (DDA) algorithm uses the slope of the line to determine each successive pixel position.

Algorithm Steps:

  1. Calculate dx = x₁ - x₀ and dy = y₁ - y₀

  2. Determine steps = max(|dx|, |dy|)

  3. Calculate X-increment = dx/steps, Y-increment = dy/steps

  4. Plot each pixel by repeatedly adding the increments

C++ Code Implementation:

#include <graphics.h>
#include <conio.h>
#include <iostream.h>
#include <math.h>

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI");
    
    int x0, y0, x1, y1;
    cout << "Enter starting point (x0 y0): ";
    cin >> x0 >> y0;
    cout << "Enter ending point (x1 y1): ";
    cin >> x1 >> y1;
    
    // Calculate dx and dy
    int dx = x1 - x0;
    int dy = y1 - y0;
    
    // Calculate steps required
    int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
    
    // Calculate increment in x and y for each step
    float xIncrement = (float)dx / steps;
    float yIncrement = (float)dy / steps;
    
    // Start from first point
    float x = x0;
    float y = y0;
    
    // Plot the first point
    putpixel(round(x), round(y), WHITE);
    
    // Plot subsequent points
    for(int i = 0; i < steps; i++) {
        x += xIncrement;
        y += yIncrement;
        putpixel(round(x), round(y), WHITE);
    }
    
    getch();
    closegraph();
}

Lab Questions:

  1. Why do we need to use float variables for x and y in DDA?

  2. What happens if we don't use the round() function when plotting pixels?


Task 2: Implement Bresenham's Line Drawing Algorithm

Bresenham's algorithm uses only integer arithmetic, making it much faster than DDA. It's the industry standard for line drawing.

C++ Code Implementation:

#include <graphics.h>
#include <conio.h>
#include <iostream.h>

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI");
    
    int x0, y0, x1, y1;
    cout << "Enter starting point (x0 y0): ";
    cin >> x0 >> y0;
    cout << "Enter ending point (x1 y1): ";
    cin >> x1 >> y1;
    
    int dx = abs(x1 - x0);
    int dy = abs(y1 - y0);
    int sx = (x0 < x1) ? 1 : -1;  // x direction
    int sy = (y0 < y1) ? 1 : -1;  // y direction
    int err = dx - dy;
    
    while(true) {
        putpixel(x0, y0, WHITE);  // Plot current point
        
        if(x0 == x1 && y0 == y1) break;  // Reached end point
        
        int err2 = 2 * err;
        
        if(err2 > -dy) {
            err -= dy;
            x0 += sx;
        }
        
        if(err2 < dx) {
            err += dx;
            y0 += sy;
        }
    }
    
    getch();
    closegraph();
}

Lab Questions:

  1. Explain the role of the decision parameter err in Bresenham's algorithm.

  2. Why is Bresenham's algorithm more efficient than DDA for line drawing?


Task 3: Create a Custom myLine() Function

Now let's create a reusable line drawing function that can be used throughout your graphics programs.

C++ Code Implementation (using Bresenham's algorithm):

#include <graphics.h>
#include <conio.h>
#include <iostream.h>

// Custom line drawing function using Bresenham's algorithm
void myLine(int x0, int y0, int x1, int y1, int color = WHITE) {
    int dx = abs(x1 - x0);
    int dy = abs(y1 - y0);
    int sx = (x0 < x1) ? 1 : -1;
    int sy = (y0 < y1) ? 1 : -1;
    int err = dx - dy;
    
    while(true) {
        putpixel(x0, y0, color);
        
        if(x0 == x1 && y0 == y1) break;
        
        int err2 = 2 * err;
        
        if(err2 > -dy) {
            err -= dy;
            x0 += sx;
        }
        
        if(err2 < dx) {
            err += dx;
            y0 += sy;
        }
    }
}

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI");
    
    // Test our custom function
    myLine(100, 100, 300, 150, RED);    // Red line
    myLine(100, 200, 300, 200, GREEN);  // Green horizontal line
    myLine(150, 50, 150, 250, BLUE);    // Blue vertical line
    
    getch();
    closegraph();
}

Task 4: Create a Rectangle using myLine() Function

Now we'll use our custom myLine() function to build more complex shapes - starting with a rectangle.

                   Task 4: Draw Rectangle

C++ Code Implementation:

#include <graphics.h>
#include <conio.h>
#include <iostream.h>

// Include the myLine function from previous task
void myLine(int x0, int y0, int x1, int y1, int color = WHITE) {
    // Copy the myLine implementation from Task 3 here
    int dx = abs(x1 - x0);
    int dy = abs(y1 - y0);
    int sx = (x0 < x1) ? 1 : -1;
    int sy = (y0 < y1) ? 1 : -1;
    int err = dx - dy;
    
    while(true) {
        putpixel(x0, y0, color);
        if(x0 == x1 && y0 == y1) break;
        int err2 = 2 * err;
        if(err2 > -dy) {
            err -= dy;
            x0 += sx;
        }
        if(err2 < dx) {
            err += dx;
            y0 += sy;
        }
    }
}

// Custom rectangle drawing function
void myRectangle(int x0, int y0, int x1, int y1, int color = WHITE) {
    // Top line
    myLine(x0, y0, x1, y0, color);
    // Right line
    myLine(x1, y0, x1, y1, color);
    // Bottom line
    myLine(x1, y1, x0, y1, color);
    // Left line
    myLine(x0, y1, x0, y0, color);
}

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI");
    
    // Draw multiple rectangles
    myRectangle(100, 100, 200, 150, RED);
    myRectangle(150, 120, 250, 180, GREEN);
    myRectangle(200, 80, 300, 130, BLUE);
    
    cout << "Three rectangles drawn using custom myLine function!";
    
    getch();
    closegraph();
}

Lab Questions:

  1. What are the advantages of creating reusable functions like myLine() and myRectangle()?

  2. How would you modify myRectangle() to draw a filled rectangle?


Bonus Challenge Tasks

Ready for more? Here are 3 additional tasks to enhance your graphics programming skills.


Challenge 5: Pattern Drawing with Lines

Task: Create a program that draws a geometric pattern using multiple lines (e.g., a star, grid, or abstract pattern).

Solution:

void drawPattern() {
    // Draw a star pattern
    for(int i = 0; i < 360; i += 30) {
        int x2 = 300 + 100 * cos(i * 3.14 / 180);
        int y2 = 200 + 100 * sin(i * 3.14 / 180);
        myLine(300, 200, x2, y2, i / 30 + 1);
    }
}

Challenge 6: Animated Line Drawing

Task: Modify the line drawing algorithm to animate the line being drawn from start to end point.

Solution:

void animatedLine(int x0, int y0, int x1, int y1) {
    // Use DDA for smooth animation
    int dx = x1 - x0;
    int dy = y1 - y0;
    int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
    float xIncrement = (float)dx / steps;
    float yIncrement = (float)dy / steps;
    
    float x = x0;
    float y = y0;
    
    for(int i = 0; i < steps; i++) {
        putpixel(round(x), round(y), WHITE);
        delay(10);  // Small delay to see animation
        x += xIncrement;
        y += yIncrement;
    }
}

Challenge 7: Triangle Drawing Function

Task: Create a myTriangle() function that draws a triangle using three myLine() calls.

Solution:

void myTriangle(int x0, int y0, int x1, int y1, int x2, int y2, int color = WHITE) {
    myLine(x0, y0, x1, y1, color);  // Side 1
    myLine(x1, y1, x2, y2, color);  // Side 2
    myLine(x2, y2, x0, y0, color);  // Side 3
}

MATLAB Implementation (For Reference)

Task 1 - DDA Algorithm in MATLAB:

matlab
% DDA Line Drawing in MATLAB
function dda_line(x0, y0, x1, y1)
    dx = x1 - x0;
    dy = y1 - y0;
    steps = max(abs(dx), abs(dy));
    
    xIncrement = dx / steps;
    yIncrement = dy / steps;
    
    x = x0;
    y = y0;
    
    hold on;
    for i = 1:steps
        plot(round(x), round(y), 'b.');
        x = x + xIncrement;
        y = y + yIncrement;
    end
    hold off;
    axis equal;
    grid on;
end

Lab Submission Requirements

  1. Source Code: Submit all .cpp files for Tasks 1-4 and any bonus challenges you attempted.

  2. Output Screenshots: Provide screenshots showing your lines and rectangles.

  3. Answers: Include a separate document with answers to all "Lab Questions."

  4. Signed Printouts: Bring printed copies of your code, signed by the lab instructor.

Success in this lab will give you the foundation needed for all future computer graphics work!

Good luck, and happy coding!

Instructor: Prof. Dr. Zeeshan Bhatti
YouTube Channel: Zeeshan Academy


Extra Task
Task 4: Create a custom Rectangle Function using your own myLine() function. The rectangle function should create a rectangle using four lines as fallow:

void myRectangle(int x0, int y0, int x1, int y1) {
    myLine(                       ); \\Line 1
    myLine(                       ) ; \\Line 2
    myLine(                       ); \\ Line 3
    myLine(                       ); \\Line 4

 }
Task 4: Draw Rectangle


No comments:

Post a Comment

Featured post

👉 🔥 Master Full Stack Web Development | Week-1 Lecture-1 - HTML & Frontend vs Backend, Dr. Zeeshan Bhatti

  Hey there, future coders! Welcome to the most exciting journey of your life. I'm  Dr. Zeeshan Bhatti  from  Zeeshan Academy , and you...