#include<stdio.
h>
#include<conio.h>
#include<graphics.h>
#include<math.h>
struct point3D {
int x, y, z;
};
void drawCube(struct point3D p[]);
void parallelProjection(struct point3D p[]);
void perspectiveProjection(struct point3D p[], float d);
void translate3D(struct point3D p[], int tx, int ty, int tz);
void scale3D(struct point3D p[], float sx, float sy, float sz);
void rotate3D_X(struct point3D p[], float angle);
void rotate3D_Y(struct point3D p[], float angle);
void rotate3D_Z(struct point3D p[], float angle);
void main()
{
int gd = DETECT, gm, choice, tx, ty, tz;
float sx, sy, sz, angle, d;
struct point3D cube[8] = {
{100, 100, 100}, {200, 100, 100}, {200, 200, 100}, {100, 200, 100},
{100, 100, 200}, {200, 100, 200}, {200, 200, 200}, {100, 200, 200}
};
initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");
cleardevice();
outtextxy(10, 10, "Original Cube (Parallel Projection)");
parallelProjection(cube);
getch();
cleardevice();
closegraph();
printf("\n3D Transformations Menu:\n");
printf("1. Translation\n");
printf("2. Scaling\n");
printf("3. Rotation about X-axis\n");
printf("4. Rotation about Y-axis\n");
printf("5. Rotation about Z-axis\n");
printf("6. Parallel Projection\n");
printf("7. Perspective Projection\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("\nEnter translation factors (tx ty tz): ");
scanf("%d %d %d", &tx, &ty, &tz);
translate3D(cube, tx, ty, tz);
break;
case 2:
printf("\nEnter scaling factors (sx sy sz): ");
scanf("%f %f %f", &sx, &sy, &sz);
scale3D(cube, sx, sy, sz);
break;
case 3:
printf("\nEnter rotation angle about X-axis (degrees): ");
scanf("%f", &angle);
rotate3D_X(cube, angle);
break;
case 4:
printf("\nEnter rotation angle about Y-axis (degrees): ");
scanf("%f", &angle);
rotate3D_Y(cube, angle);
break;
case 5:
printf("\nEnter rotation angle about Z-axis (degrees): ");
scanf("%f", &angle);
rotate3D_Z(cube, angle);
break;
case 6:
break; // No transformation needed, already using parallel projection
case 7:
printf("\nEnter distance from viewer to projection plane (d): ");
scanf("%f", &d);
break;
default:
printf("\nInvalid choice!");
return;
}
initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");
cleardevice();
if(choice == 7)
{
outtextxy(10, 10, "Perspective Projection");
perspectiveProjection(cube, d);
}
else
{
outtextxy(10, 10, "After Transformation (Parallel Projection)");
parallelProjection(cube);
}
getch();
closegraph();
}
// Draw cube edges
void drawCube(struct point3D p[])
{
line(p[0].x, p[0].y, p[1].x, p[1].y);
line(p[1].x, p[1].y, p[2].x, p[2].y);
line(p[2].x, p[2].y, p[3].x, p[3].y);
line(p[3].x, p[3].y, p[0].x, p[0].y);
line(p[4].x, p[4].y, p[5].x, p[5].y);
line(p[5].x, p[5].y, p[6].x, p[6].y);
line(p[6].x, p[6].y, p[7].x, p[7].y);
line(p[7].x, p[7].y, p[4].x, p[4].y);
line(p[0].x, p[0].y, p[4].x, p[4].y);
line(p[1].x, p[1].y, p[5].x, p[5].y);
line(p[2].x, p[2].y, p[6].x, p[6].y);
line(p[3].x, p[3].y, p[7].x, p[7].y);
}
// Parallel projection: simply ignore z-coordinate
void parallelProjection(struct point3D p[])
{
drawCube(p);
}
// Perspective projection: based on distance d
void perspectiveProjection(struct point3D p[], float d)
{
struct point3D pp[8];
int i;
for(i = 0; i < 8; i++)
{
pp[i].x = (int)((float)p[i].x / (1 + (float)p[i].z/d));
pp[i].y = (int)((float)p[i].y / (1 + (float)p[i].z/d));
}
drawCube(pp);
}
// ------------- 3D Transformations -------------
void translate3D(struct point3D p[], int tx, int ty, int tz)
{
int i;
for(i = 0; i < 8; i++)
{
p[i].x += tx;
p[i].y += ty;
p[i].z += tz;
}
}
void scale3D(struct point3D p[], float sx, float sy, float sz)
{
int i;
for(i = 0; i < 8; i++)
{
p[i].x = (int)(p[i].x * sx);
p[i].y = (int)(p[i].y * sy);
p[i].z = (int)(p[i].z * sz);
}
}
void rotate3D_X(struct point3D p[], float angle)
{
int i;
float rad = angle * (3.14159 / 180);
float y, z;
for(i = 0; i < 8; i++)
{
y = p[i].y;
z = p[i].z;
p[i].y = (int)(y*cos(rad) - z*sin(rad));
p[i].z = (int)(y*sin(rad) + z*cos(rad));
}
}
void rotate3D_Y(struct point3D p[], float angle)
{
int i;
float rad = angle * (3.14159 / 180);
float x, z;
for(i = 0; i < 8; i++)
{
x = p[i].x;
z = p[i].z;
p[i].x = (int)(x*cos(rad) + z*sin(rad));
p[i].z = (int)(-x*sin(rad) + z*cos(rad));
}
}
void rotate3D_Z(struct point3D p[], float angle)
{
int i;
float rad = angle * (3.14159 / 180);
float x, y;
for(i = 0; i < 8; i++)
{
x = p[i].x;
y = p[i].y;
p[i].x = (int)(x*cos(rad) - y*sin(rad));
p[i].y = (int)(x*sin(rad) + y*cos(rad));
}
}