Write a c program to apply various 2D transformations on a 2D object (use homogenous coordinates).

Below is a C program that demonstrates how to apply various 2D transformations (such as translation, scaling, rotation, and reflection) on a 2D object using homogeneous coordinates.

2D Transformation using Homogeneous Coordinates in C

The program performs the following transformations on a 2D object (a polygon):

  • Translation
  • Scaling
  • Rotation
  • Reflection

We'll represent the 2D points in homogeneous coordinates using a 3x1 matrix (a vector with x, y, and 1), and apply transformation matrices to modify the object.

	#include <stdio.h>
    #include <graphics.h>
    #include <math.h>
    
    #define MAX_VERTICES 10
    
    // Structure to represent a point in homogeneous coordinates (x, y, 1)
    typedef struct {
        float x, y, w;
    } Point;
    
    // Function to multiply a point by a transformation matrix
    Point multiplyMatrix(Point p, float matrix[3][3]) {
        Point result;
        result.x = matrix[0][0] * p.x + matrix[0][1] * p.y + matrix[0][2] * p.w;
        result.y = matrix[1][0] * p.x + matrix[1][1] * p.y + matrix[1][2] * p.w;
        result.w = matrix[2][0] * p.x + matrix[2][1] * p.y + matrix[2][2] * p.w;
        return result;
    }
    
    // Function to translate a point by (tx, ty)
    void translate(float tx, float ty, float matrix[3][3]) {
        matrix[0][0] = 1;
        matrix[0][1] = 0;
        matrix[0][2] = tx;
        matrix[1][0] = 0;
        matrix[1][1] = 1;
        matrix[1][2] = ty;
        matrix[2][0] = 0;
        matrix[2][1] = 0;
        matrix[2][2] = 1;
    }
    
    // Function to scale a point by (sx, sy)
    void scale(float sx, float sy, float matrix[3][3]) {
        matrix[0][0] = sx;
        matrix[0][1] = 0;
        matrix[0][2] = 0;
        matrix[1][0] = 0;
        matrix[1][1] = sy;
        matrix[1][2] = 0;
        matrix[2][0] = 0;
        matrix[2][1] = 0;
        matrix[2][2] = 1;
    }
    
    // Function to rotate a point by an angle (in degrees)
    void rotate(float angle, float matrix[3][3]) {
        float rad = angle * M_PI / 180.0;  // Convert angle to radians
        matrix[0][0] = cos(rad);
        matrix[0][1] = -sin(rad);
        matrix[0][2] = 0;
        matrix[1][0] = sin(rad);
        matrix[1][1] = cos(rad);
        matrix[1][2] = 0;
        matrix[2][0] = 0;
        matrix[2][1] = 0;
        matrix[2][2] = 1;
    }
    
    // Function to reflect a point about the x-axis
    void reflectX(float matrix[3][3]) {
        matrix[0][0] = 1;
        matrix[0][1] = 0;
        matrix[0][2] = 0;
        matrix[1][0] = 0;
        matrix[1][1] = -1;
        matrix[1][2] = 0;
        matrix[2][0] = 0;
        matrix[2][1] = 0;
        matrix[2][2] = 1;
    }
    
    // Function to reflect a point about the y-axis
    void reflectY(float matrix[3][3]) {
        matrix[0][0] = -1;
        matrix[0][1] = 0;
        matrix[0][2] = 0;
        matrix[1][0] = 0;
        matrix[1][1] = 1;
        matrix[1][2] = 0;
        matrix[2][0] = 0;
        matrix[2][1] = 0;
        matrix[2][2] = 1;
    }
    
    // Function to plot a polygon on the screen
    void plotPolygon(Point polygon[], int n) {
        for (int i = 0; i < n - 1; i++) {
            line(polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y);
        }
        line(polygon[n - 1].x, polygon[n - 1].y, polygon[0].x, polygon[0].y);
    }
    
    int main() {
        int gd = DETECT, gm;
        initgraph(&gd, &gm, "");  // Initialize graphics mode
    
        int n;
        Point polygon[MAX_VERTICES];
    
        // Input the number of vertices of the polygon
        printf("Enter the number of vertices of the polygon: ");
        scanf("%d", &n);
    
        // Input the coordinates of the polygon
        printf("Enter the coordinates of the polygon vertices (x y):\n");
        for (int i = 0; i < n; i++) {
            printf("Vertex %d: ", i + 1);
            scanf("%f %f", &polygon[i].x, &polygon[i].y);
            polygon[i].w = 1;  // Homogeneous coordinate (w = 1 for 2D)
        }
    
        // Draw the original polygon
        setcolor(WHITE);
        plotPolygon(polygon, n);
    
        // Choose the transformation
        int choice;
        printf("\nChoose the transformation to apply:\n");
        printf("1. Translation\n");
        printf("2. Scaling\n");
        printf("3. Rotation\n");
        printf("4. Reflection about X-axis\n");
        printf("5. Reflection about Y-axis\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
    
        float matrix[3][3] = { 0 };
        Point transformedPolygon[MAX_VERTICES];
    
        switch (choice) {
            case 1: {
                float tx, ty;
                printf("Enter translation vector (tx, ty): ");
                scanf("%f %f", &tx, &ty);
                translate(tx, ty, matrix);
                break;
            }
            case 2: {
                float sx, sy;
                printf("Enter scaling factors (sx, sy): ");
                scanf("%f %f", &sx, &sy);
                scale(sx, sy, matrix);
                break;
            }
            case 3: {
                float angle;
                printf("Enter rotation angle (in degrees): ");
                scanf("%f", &angle);
                rotate(angle, matrix);
                break;
            }
            case 4: {
                reflectX(matrix);
                break;
            }
            case 5: {
                reflectY(matrix);
                break;
            }
            default:
                printf("Invalid choice\n");
                closegraph();
                return 0;
        }
    
        // Apply the transformation to all vertices of the polygon
        for (int i = 0; i < n; i++) {
            transformedPolygon[i] = multiplyMatrix(polygon[i], matrix);
        }
    
        // Draw the transformed polygon
        setcolor(RED);
        plotPolygon(transformedPolygon, n);
    
        // Wait for the user to press a key before closing the graphics window
        getch();
        closegraph();
        return 0;
    }