Write a c program to clip a polygon using Sutherland Hodgeman algorithm.
The Sutherland-Hodgman Polygon Clipping Algorithm is a method used to clip a polygon against a rectangular clipping window. It works by iteratively clipping the polygon against each edge of the clipping window. Below is a C program that implements the Sutherland-Hodgman polygon clipping algorithm:
#include <stdio.h>
#include <graphics.h>
#define MAX_POINTS 20
// Structure to represent a point
typedef struct {
int x, y;
} Point;
// Function to clip the polygon against a single edge of the clipping window
int clipAgainstEdge(Point inputPolygon[], int inputSize, Point outputPolygon[], int x1, int y1, int x2, int y2) {
Point newPoints[MAX_POINTS];
int newSize = 0;
// Iterate through all edges of the input polygon
for (int i = 0; i < inputSize; i++) {
int j = (i + 1) % inputSize;
Point currentPoint = inputPolygon[i];
Point nextPoint = inputPolygon[j];
// Calculate the position of the current and next points relative to the edge
int currentPos = (x2 - x1) * (currentPoint.y - y1) - (y2 - y1) * (currentPoint.x - x1);
int nextPos = (x2 - x1) * (nextPoint.y - y1) - (y2 - y1) * (nextPoint.x - x1);
// Case 1: Both points are inside the edge
if (currentPos >= 0 && nextPos >= 0) {
newPoints[newSize++] = nextPoint;
}
// Case 2: Current point is inside, and next point is outside
else if (currentPos >= 0 && nextPos < 0) {
// Find the intersection point
int xIntersect = x1 + (x2 - x1) * (currentPoint.y - y1) - (y2 - y1) * (currentPoint.x - x1);
int yIntersect = y1 + (y2 - y1) * (currentPoint.y - y1) - (y2 - y1) * (currentPoint.x - x1);
newPoints[newSize++] = (Point){xIntersect, yIntersect};
}
// Case 3: Current point is outside, and next point is inside
else if (currentPos < 0 && nextPos >= 0) {
// Find the intersection point
int xIntersect = x1 + (x2 - x1) * (currentPoint.y - y1) - (y2 - y1) * (currentPoint.x - x1);
int yIntersect = y1 + (y2 - y1) * (currentPoint.y - y1) - (y2 - y1) * (currentPoint.x - x1);
newPoints[newSize++] = (Point){xIntersect, yIntersect};
newPoints[newSize++] = nextPoint;
}
// Case 4: Both points are outside (do nothing)
}
// Copy the new points to the output polygon
for (int i = 0; i < newSize; i++) {
outputPolygon[i] = newPoints[i];
}
return newSize;
}
// Function to clip the polygon against all edges of the clipping window
void sutherlandHodgmanClip(Point inputPolygon[], int inputSize, Point outputPolygon[], int *outputSize, int xMin, int yMin, int xMax, int yMax) {
Point tempPolygon1[MAX_POINTS];
Point tempPolygon2[MAX_POINTS];
int tempSize;
// Clip against the left edge
tempSize = clipAgainstEdge(inputPolygon, inputSize, tempPolygon1, xMin, yMin, xMin, yMax);
// Clip against the top edge
tempSize = clipAgainstEdge(tempPolygon1, tempSize, tempPolygon2, xMin, yMax, xMax, yMax);
// Clip against the right edge
tempSize = clipAgainstEdge(tempPolygon2, tempSize, tempPolygon1, xMax, yMax, xMax, yMin);
// Clip against the bottom edge
tempSize = clipAgainstEdge(tempPolygon1, tempSize, outputPolygon, xMax, yMin, xMin, yMin);
*outputSize = tempSize;
}
int main() {
int gd = DETECT, gm;
Point inputPolygon[MAX_POINTS];
Point outputPolygon[MAX_POINTS];
int inputSize, outputSize;
// Initialize graphics mode
initgraph(&gd, &gm, NULL);
// Define the clipping window
int xMin = 100, yMin = 100, xMax = 400, yMax = 300;
// Draw the clipping window
rectangle(xMin, yMin, xMax, yMax);
// Input the polygon
printf("Enter the number of vertices in the polygon: ");
scanf("%d", &inputSize);
printf("Enter the coordinates of the vertices (x y):\n");
for (int i = 0; i < inputSize; i++) {
scanf("%d %d", &inputPolygon[i].x, &inputPolygon[i].y);
}
// Draw the original polygon
setcolor(WHITE);
for (int i = 0; i < inputSize; i++) {
int j = (i + 1) % inputSize;
line(inputPolygon[i].x, inputPolygon[i].y, inputPolygon[j].x, inputPolygon[j].y);
}
// Clip the polygon using Sutherland-Hodgman algorithm
sutherlandHodgmanClip(inputPolygon, inputSize, outputPolygon, &outputSize, xMin, yMin, xMax, yMax);
// Draw the clipped polygon
setcolor(RED);
for (int i = 0; i < outputSize; i++) {
int j = (i + 1) % outputSize;
line(outputPolygon[i].x, outputPolygon[i].y, outputPolygon[j].x, outputPolygon[j].y);
}
// Wait for a key press
getch();
// Close the graphics mode
closegraph();
return 0;
}