Tuesday, 19 April 2016

Computer Graphics Hands-On Lab: Implementing 2D Transformations in C++


Computer Graphics Hands-On Lab: Implementing 2D Transformations in C++ 

By: Dr. Zeeshan Bhatti


Solving 2D Transformation problem in Computer Graphics | 2D Translate Rotate Matrices Problem 🎮10

Lab Objectives

Welcome, everyone, to a practical deep-dive into the world of 2D transformations! By the end of this lab session, you will:

  • Understand how transformation matrices are implemented in code.

  • Gain hands-on experience writing programs for fundamental 2D transformations: Translation, Rotation, Scaling, and Shearing.

  • Be able to visualize these transformations graphically using C++ (with the Borland Graphics Interface) and MATLAB.

  • Combine multiple transformations to manipulate simple objects.


Pre-Lab Task: The Matrix Behind the Magic

Task 1: Matrix Operations in MATLAB vs. C++/Java

Before we start coding transformations, it's crucial to understand the engine behind them: matrices. How we handle them differs significantly between languages.

In MATLAB:
MATLAB is an abbreviation for MATrix LABoratory. It's designed for this. Operations are intuitive and high-level.

  • Defining a Matrix: A = [1 2; 3 4]; creates a 2x2 matrix.

  • Matrix Multiplication: Uses the * operator. C = A * B; performs proper matrix multiplication.

  • Solving Systems: The backslash operator \ is powerful. x = A \ b solves for x in the equation A*x = b.

  • It's native: You don't need to include special libraries for basic matrix operations.

In C++/Java:
These are general-purpose languages. You have to build the matrix functionality yourself or use libraries.

  • Native Approach: You typically use multi-dimensional arrays: int matrix[2][2] = {{1, 2}, {3, 4}};.

  • Manual Multiplication: You must write nested for loops to implement the matrix multiplication algorithm.

  • Using Libraries: To avoid reinventing the wheel, you can use libraries like:

    • C++: The Eigen library (highly recommended for serious work), Armadillo, or the std::valarray.

    • Java: The Apache Commons Math library provides a RealMatrix class.

  • Key Difference: The * operator in C++/Java on arrays does not perform matrix multiplication; it operates element-wise or on pointers. You must use a function or overload the operator yourself.

Question for Thought: Why might it be easier to prototype a graphics algorithm in MATLAB, but then implement the final version in C++?


The Core Programming Tasks

Let's get our hands dirty with code. We'll start with C++ using the classic Borland Graphics Interface (BGI) for simple graphical output. Ensure you have a compatible IDE like Turbo C++ or a modern equivalent with BGI support (e.g., WinBGIM for Code::Blocks).


Task 2: Implementing 2D Scaling in C++

Scaling changes the size of an object. This program scales a triangle relative to its own centroid (the average of its points).

C++ Code:

cpp
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<math.h>

int x1, y1, x2, y2, x3, y3, mx, my;

void draw();
void scale();

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI"); // Use your BGI path
    printf("Enter the 1st point for the triangle: ");
    scanf("%d%d", &x1, &y1);
    printf("Enter the 2nd point for the triangle: ");
    scanf("%d%d", &x2, &y2);
    printf("Enter the 3rd point for the triangle: ");
    scanf("%d%d", &x3, &y3);
    draw();
    scale();
    getch();
    closegraph();
}

void draw() {
    line(x1, y1, x2, y2);
    line(x2, y2, x3, y3);
    line(x3, y3, x1, y1);
}

void scale() {
    int x, y, a1, a2, a3, b1, b2, b3;
    printf("Enter the scaling factors (x y): ");
    scanf("%d%d", &x, &y);

    // Calculate centroid (fixed point for scaling)
    mx = (x1 + x2 + x3) / 3;
    my = (y1 + y2 + y3) / 3;

    cleardevice();

    // Scale each point relative to the centroid
    a1 = mx + (x1 - mx) * x;
    b1 = my + (y1 - my) * y;
    a2 = mx + (x2 - mx) * x;
    b2 = my + (y2 - my) * y;
    a3 = mx + (x3 - mx) * x;
    b3 = my + (y3 - my) * y;

    // Draw the new, scaled triangle
    line(a1, b1, a2, b2);
    line(a2, b2, a3, b3);
    line(a3, b3, a1, b1);
}

Lab Questions:

  1. What is the purpose of calculating the centroid (mxmy) before scaling?

  2. What would happen if you scaled each point directly (e.g., a1 = x1 * x;) without using the centroid? Try it and describe the result.


Task 3: Implementing 2D Rotation in C++

Rotation turns an object around a specific point. This program rotates a triangle around one of its own vertices (x2, y2).

C++ Code:

cpp
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<math.h>

void TriAngle(int x1, int y1, int x2, int y2, int x3, int y3);
void Rotate(int x1, int y1, int x2, int y2, int x3, int y3);

void main() {
    int gd = DETECT, gm;
    int x1, y1, x2, y2, x3, y3;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI");
    printf("Enter the 1st point for the triangle: ");
    scanf("%d%d", &x1, &y1);
    printf("Enter the 2nd point for the triangle: ");
    scanf("%d%d", &x2, &y2);
    printf("Enter the 3rd point for the triangle: ");
    scanf("%d%d", &x3, &y3);
    TriAngle(x1, y1, x2, y2, x3, y3);
    getch();
    cleardevice();
    Rotate(x1, y1, x2, y2, x3, y3);
    setcolor(1); // Change color for the rotated triangle
    getch();
    closegraph();
}

void TriAngle(int x1, int y1, int x2, int y2, int x3, int y3) {
    line(x1, y1, x2, y2);
    line(x2, y2, x3, y3);
    line(x3, y3, x1, y1);
}

void Rotate(int x1, int y1, int x2, int y2, int x3, int y3) {
    int a1, b1, a2, b2, a3, b3, p = x2, q = y2; // Pivot point is (x2, y2)
    float Angle;
    printf("Enter the angle for rotation (in degrees): ");
    scanf("%f", &Angle);

    Angle = (Angle * 3.14) / 180; // Convert to radians

    // Apply the rotation matrix formula for each point
    a1 = p + (x1 - p) * cos(Angle) - (y1 - q) * sin(Angle);
    b1 = q + (x1 - p) * sin(Angle) + (y1 - q) * cos(Angle);
    a2 = p + (x2 - p) * cos(Angle) - (y2 - q) * sin(Angle);
    b2 = q + (x2 - p) * sin(Angle) + (y2 - q) * cos(Angle);
    a3 = p + (x3 - p) * cos(Angle) - (y3 - q) * sin(Angle);
    b3 = q + (x3 - p) * sin(Angle) + (y3 - q) * cos(Angle);

    printf("Rotated Triangle Coordinates: (%d,%d), (%d,%d), (%d,%d)\n", a1, b1, a2, b2, a3, b3);
    TriAngle(a1, b1, a2, b2, a3, b3);
}

Lab Questions:

  1. The pivot point in this code is fixed at (x2, y2). How would you modify the code to allow the user to input any arbitrary pivot point?

  2. Why is it necessary to convert the angle from degrees to radians?


Task 4: Implementing 2D Translation in C++

Translation moves an object by a fixed amount in the x and y directions. It's the simplest transformation.

C++ Code:

cpp
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<math.h>

int x1, y1, x2, y2, x3, y3;

void draw();
void tri();

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "C:\\Turboc3\\BGI");
    printf("Enter the 1st point for the triangle: ");
    scanf("%d%d", &x1, &y1);
    printf("Enter the 2nd point for the triangle: ");
    scanf("%d%d", &x2, &y2);
    printf("Enter the 3rd point for the triangle: ");
    scanf("%d%d", &x3, &y3);
    cleardevice();
    draw();
    getch();
    tri();
    getch();
    closegraph();
}

void draw() {
    line(x1, y1, x2, y2);
    line(x2, y2, x3, y3);
    line(x3, y3, x1, y1);
}

void tri() {
    int x, y, a1, a2, a3, b1, b2, b3;
    printf("Enter the translation coordinates (dx dy): ");
    scanf("%d%d", &x, &y);
    cleardevice();

    // Translate each point
    a1 = x1 + x;
    b1 = y1 + y;
    a2 = x2 + x;
    b2 = y2 + y;
    a3 = x3 + x;
    b3 = y3 + y;

    // Draw the translated triangle
    line(a1, b1, a2, b2);
    line(a2, b2, a3, b3);
    line(a3, b3, a1, b1);
}

Lab Question:

  1. How does the code for translation demonstrate that it is a straightforward addition to each vertex, unlike rotation and scaling?


MATLAB Implementation Tasks

MATLAB's strength lies in its concise matrix operations. Notice how the code is much shorter and focuses on the transformation matrix itself.

Task 5: 2D Translation in MATLAB

matlab
% Simple demo of 2D Translation in dx,dy in MATLAB
dx = 3; % set translation values
dy = 2;
pts = [1 1 4 4 1; 1 4 4 1 1]; % Define a square

% Plot original square
figure(1)
plot(pts(1,1:end), pts(2,1:end), 'b*-');
axis([0 10 0 10]); grid on; hold on;

% Create 2D Translation matrix (Homogeneous Coordinates)
trans = [1 0 dx; 0 1 dy; 0 0 1];

% Make PTS HOMOGENEOUS
homogeneous_pts = [pts; ones(1, length(pts))];

% Translate
trans_pts = trans * homogeneous_pts;

% Plot Translated box
plot(trans_pts(1,1:end), trans_pts(2,1:end), 'r*-');
title('2D Translation');
legend('Original', 'Translated');
hold off;

Task 6: 2D Rotation in MATLAB

matlab
% Simple demo of 2D rotation in MATLAB
pts = [1 1 4 4 1; 1 4 4 1 1]; % Define a square

% Plot original square
figure(1)
plot(pts(1,1:end), pts(2,1:end), 'b*-');
axis([-8 8 -8 8]); grid on; hold on;

% Create a 2D rotation matrix (30 degrees)
theta = 30;
rot = [cosd(theta) sind(theta); -sind(theta) cosd(theta)];

% Do Rotation
rot_pts = rot * pts;

% Plot Rotated box
plot(rot_pts(1,1:end), rot_pts(2,1:end), 'r*-');
title('2D Rotation');
legend('Original', 'Rotated');
hold off;

Task 7: 2D Shear in MATLAB

matlab
% shear_demo_2D.m
close all; clear all;

% Simple demo of 2D Shear in X in MATLAB
k = 1.5; % shear factor
pts = [1 1 4 4 1; 1 4 4 1 1]; % Define a square

% Plot original square
figure(1)
plot(pts(1,1:end), pts(2,1:end), 'b*-');
axis([0 15 0 5]); grid on; hold on;

% Create a 2D Shear in X matrix
shear = [1 k; 0 1];

% Do Shear
shear_pts = shear * pts;

% Plot Sheared box
plot(shear_pts(1,1:end), shear_pts(2,1:end), 'r*-');
title('2D Shear in X-direction');
legend('Original', 'Sheared');
hold off;

Bonus Challenge Tasks (C++ with BGI)

Ready to level up? Here are 5 extra tasks to solidify your understanding.

Challenge 1: Combined Transformation

Task: Modify the C++ code to perform a sequence of transformations: first scale the triangle by (2, 2), then rotate it by 45 degrees, and finally translate it by (10, 10). Draw the object after each step in a different color.

  • Hint: You will need to apply the formulas from the previous tasks sequentially to each vertex.

Challenge 2: Reflection Transformation

Task: Write a program to perform a 2D reflection about the Y-axis. The reflection matrix for Y-axis is [-1, 0; 0, 1].

  • Code Snippet:

    cpp
    // For each point (x, y)
    int x_reflected = -x + getmaxx()/2; // Reflect and adjust to screen center
    int y_reflected = y;

Challenge 3: User-Defined Pivot Point

Task: Modify the rotation program (Task 3) to allow the user to input the coordinates (p, q) of the pivot point for rotation, instead of using a fixed vertex.

  • Solution: Simply change the lines p = x2; q = y2; to scanf statements that get p and q from the user.

Challenge 4: Drawing a Rectangle

Task: All previous tasks use a triangle. Write a program that draws a rectangle (defined by four points) and then applies shearing in the Y-direction. The shear matrix for Y-shear is [1, 0; shY, 1].

  • Code Snippet for Y-Shear:

    cpp
    // For a point (x, y) and shear factor shY
    int x_sheared = x;
    int y_sheared = y + shY * x;

Challenge 5: Interactive Transformation

Task: Create a simple menu-driven program that asks the user which transformation to apply (Translate, Rotate, Scale) and then takes the necessary inputs (translation vector, angle, scaling factors) and displays the result.

  • Solution Outline:

    cpp
    void main() {
        // ... initgraph and input points ...
        draw();
        printf("1. Translate\n2. Rotate\n3. Scale\nEnter choice: ");
        int choice;
        scanf("%d", &choice);
        switch(choice) {
            case 1: tri(); break; // Call translation function
            case 2: Rotate(...); break; // Call rotation function
            case 3: scale(); break; // Call scaling function
        }
        getch();
        closegraph();
    }

Lab Submission Guidelines

  1. Code: Submit all your .c and .m files for the 7 core tasks and any bonus challenges you attempted.

  2. Output: For each program, provide a screenshot of the graphics window showing the original and transformed object.

  3. Answers: Include a separate document with your answers to all the "Lab Questions" embedded in the tasks.

  4. Reflection: Write a short paragraph on the most challenging part of the lab and what you learned from it.

Download the Original Lab Handout Here: Scribd Link

Good luck, and have fun transforming your code and your graphics!

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



Task 1: Search and write how Matrices are used in Matlab and in CPP or JAVA. How to Solve simple Matrices using these programming languages.

Programming Task: Write code to Solve 2D Transformation using any programming language. Write code to solve Translation, Rotation, Scaling, and Shear.


Download the Lab Handout: https://www.scribd.com/doc/309742677/Computer-Graphics-Lab-Project-4-2D-Transformation

Task 2: Write a program to implement 2D Scaling

Coding:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<math.h>
int x1,y1,x2,y2,x3,y3,mx,my;
void draw();
void scale();
void main()
{
int gd=DETECT,gm;
int c;
initgraph(&gd,&gm," ");
printf("Enter the 1st point for the triangle:");
scanf("%d%d",&x1,&y1);
printf("Enter the 2nd point for the triangle:");
scanf("%d%d",&x2,&y2);
printf("Enter the 3rd point for the triangle:");
scanf("%d%d",&x3,&y3);
draw();
scale();
}
void draw()
{
line(x1,y1,x2,y2);
line(x2,y2,x3,y3);
line(x3,y3,x1,y1);
}
void scale()
{
int x,y,a1,a2,a3,b1,b2,b3;
int mx,my;
printf("Enter the scalling coordinates");
scanf("%d%d",&x,&y);
mx=(x1+x2+x3)/3;
my=(y1+y2+y3)/3;
cleardevice();
a1=mx+(x1-mx)*x;
b1=my+(y1-my)*y;
a2=mx+(x2-mx)*x;
b2=my+(y2-my)*y;
a3=mx+(x3-mx)*x;
b3=my+(y3-my)*y;
line(a1,b1,a2,b2);
line(a2,b2,a3,b3);
line(a3,b3,a1,b1);
draw();
getch();
}


Task 3: Write a program to implement 2D Rotation



Coding:
include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<math.h>
void TriAngle(int x1,int y1,int x2,int y2,int x3,int y3);
void Rotate(int x1,int y1,int x2,int y2,int x3,int y3);
void main()
{
int gd=DETECT,gm;
int x1,y1,x2,y2,x3,y3;
initgraph(&gd,&gm," ");
printf("Enter the 1st point for the triangle:");
scanf("%d%d",&x1,&y1);
printf("Enter the 2nd point for the triangle:");
scanf("%d%d",&x2,&y2);
printf("Enter the 3rd point for the triangle:");
scanf("%d%d",&x3,&y3);
TriAngle(x1,y1,x2,y2,x3,y3);
getch();
cleardevice();
Rotate(x1,y1,x2,y2,x3,y3);
setcolor(1);
TriAngle(x1,y1,x2,y2,x3,y3);
getch();
}
void TriAngle(int x1,int y1,int x2,int y2,int x3,int y3)
{
line(x1,y1,x2,y2);
line(x2,y2,x3,y3);
line(x3,y3,x1,y1);
}
void Rotate(int x1,int y1,int x2,int y2,int x3,int y3)
{
int x,y,a1,b1,a2,b2,a3,b3,p=x2,q=y2;
float Angle;
printf("Enter the angle for rotation:");
scanf("%f",&Angle);
cleardevice();
Angle=(Angle*3.14)/180;
a1=p+(x1-p)*cos(Angle)-(y1-q)*sin(Angle);
b1=q+(x1-p)*sin(Angle)+(y1-q)*cos(Angle);
a2=p+(x2-p)*cos(Angle)-(y2-q)*sin(Angle);
b2=q+(x2-p)*sin(Angle)+(y2-q)*cos(Angle);
a3=p+(x3-p)*cos(Angle)-(y3-q)*sin(Angle);
b3=q+(x3-p)*sin(Angle)+(y3-q)*cos(Angle);
printf("Rotate");
TriAngle(a1,b1,a2,b2,a3,b3);
}



Task 4: Write a program to implement 2D Translation Triangle Program 


 Coding:


#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<math.h>
int x1,y1,x2,y2,x3,y3,mx,my;
void draw();
void tri();
void main()
{
int gd=DETECT,gm;
int c;
initgraph(&gd,&gm,"d:\\tc\\bgi ");
printf("Enter the 1st point for the triangle:");
scanf("%d%d",&x1,&y1);
printf("Enter the 2nd point for the triangle:");
scanf("%d%d",&x2,&y2);
printf("Enter the 3rd point for the triangle:");
scanf("%d%d",&x3,&y3);
cleardevice();
draw();
getch();
tri();
getch();
}
void draw()
{
line(x1,y1,x2,y2);
line(x2,y2,x3,y3);
line(x3,y3,x1,y1);
}
void tri()
{
int x,y,a1,a2,a3,b1,b2,b3;
printf("Enter the Transaction coordinates");
scanf("%d%d",&x,&y);
cleardevice();
a1=x1+x;
b1=y1+y;
a2=x2+x;
b2=y2+y;
a3=x3+x;
b3=y3+y;
line(a1,b1,a2,b2);
line(a2,b2,a3,b3);
line(a3,b3,a1,b1);
}




 Task 5: 2D Translation Using Matlab


%Simple demo of 2D Translation in dx,dy in MATLAB

dx = 3; % set translation values
dy = 2;

% create a simple box to draw and manipulate
% row 1 is x coords row 2 is y coords

pts = [1 1 4 4 1;1 4 4 1 1];
[n m] = size(pts);
% Plot box

figure(1)
plot(pts(1,1:end),pts(2,1:end),'b*-');
axis([0 5 0 5])
shg

% create a 2D Translation in dx, dy NEED TO MAKE A HOMOGENEOUS COORDS matrix

trans = [1 0 dx;0 1 dy; 0 0 1];

% Do Translation

% Make PTS HOMOGENEOUS

homogeneous_pts = [pts; ones(1,5)];

%Translate

trans_pts = trans*homogeneous_pts;

% Plot Translated box
% just extract out X and Y points to plot ignore third dimension

hold on
plot(trans_pts(1,1:end),trans_pts(2,1:end),'r*-');

axis([0 10 0 10]);

 

Task 6: 2D Rotation Using Matlab

%Simple demo of 2D rotation in MATLAB

% create a simple box to draw and manipulate
% row 1 is x coords row 2 is y coords

pts = [1 1 4 4 1;1 4 4 1 1];

% Plot box

figure(1)
plot(pts(1,1:end),pts(2,1:end),'b*-');
axis([0 5 0 5])
shg

% create a 2D rotation matrix

rot = [cos_deg(30) sin_deg(30);-sin_deg(30) cos_deg(30)]

% Do Rotation
rot_pts = rot*pts

% Plot Rotated box

hold on
plot(rot_pts(1,1:end),rot_pts(2,1:end),'r*-');

axis([-8 8 -8 8]);


Task 7: 2D Shear using Matlab

% shear_demo_2D.m
close all
clear all

%Simple demo of 2D Shear in X in MATLAB

k = 3; % shear factor

% create a simple box to draw and manipulate
% row 1 is x coords row 2 is y coords

pts = [1 1 4 4 1;1 4 4 1 1];

% Plot box

figure(1)
plot(pts(1,1:end),pts(2,1:end),'b*-');
axis([0 5 0 5])
shg

% create a 2D Shear in X matrix

shear = [1 k;0 1]

% Do Shear
shear_pts = shear*pts;

% Plot Sheared box

hold on
plot(shear_pts(1,1:end),shear_pts(2,1:end),'r*-');

axis([0 20 0 5]);

 

 

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...