3D transformations are the most basic building blocks of modern games and physics simulations.
#include <graphics.h>
#include <graphics.h>
#include <graphics.h>
Any comments or suggestions are welcome. Thankyou : )
Here we look at how to project and the 3D Matrix of a Cuboid and and rotate it about the 3 planes i.e XY, YZ, ZX using linear transformations. Projection of a 3D object is necessary as the calculations are done for a 3D object and the final scene is displayed on a 2D screen. The 3D transformations are the most basic functions performed by the GPU for rendering a 3D scene. The entire 3D object is divided into multiple polygons, mostly triangles as they are the most basic polygon but in this example we will we using rectangles. The code is written in C++ using the graphics.h header file. The code transforms each vertex individually and then draws the edges. The code can also be used for understanding the working of a simple 3D GPU and can be further implemented in an FPGA using suitable HDL code.
The code runs in Console Graphics Mode. All the header files must be properly installed for the code to work. Otherwise the code will not be compiled. Online tutorials are available and therefore not discussed here.More details of 3D graphics can be found in the Wikipedia page
The Code for XY Rotation
/////////////////////////////////////////////////////////////////////////////////////////////////
#include <math.h>
int main()
{
float x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,x5,y5,z5,x6,y6,z6,x7,y7,z7,x8,y8,z8;
float i1,j1,k1,i2,j2,k2,i3,j3,k3,i4,j4,k4,i5,j5,k5,i6,j6,k6,i7,j7,k7,i8,j8,k8;
float p1,q1,p2,q2,p3,q3,p4,q4,p5,q5,p6,q6,p7,q7,p8,q8;
int a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7,a8,b8;
//The Matrix of the Cuboid//
x1 = -100;
y1 = 100;
z1 = 0.2;
x2 = 100;
y2 = 100;
z2 = 0.2;
x3 = 100;
y3 = -100;
z3 = 0.2;
x4 = -100;
y4 = -100;
z4 = 0.2;
x5 = -100;
y5 = 100;
z5 = -0.2;
x6 = 100;
y6 = 100;
z6 = -0.2;
x7 = 100;
y7 = -100;
z7 = -0.2;
x8 = -100;
y8 = -100;
z8 = -0.2;
initwindow(700,700); //Size of the display window
for( ; ; ) //The code runs forever
{
for (float t =0; t <= 2*3.14 ; t+=0.01) //The angle 't' increases from 0 to 360 degrees
{ // The Rotation Matrix
i1 = x1*cos(t); //The points on 1st quadrant are multiplied by usual vector rotation coefficients
j1 = y1*sin(t);
k1 = z1;
i2 = x2*sin(t); *//The points on 2nd quadrant are multiplied by the f(x + pi/2); the (-)ve sign is already present before the vertex coordinates//*
j2 = y2*cos(t);
j2 = y2*cos(t);
k2 = z2;
i3 = x3*cos(t);
j3 = y3*sin(t);
k3 = z3;
i4 = x4*sin(t);
j4 = y4*cos(t);
k4 = z4;
i5 = x5*cos(t);
j5 = y5*sin(t);
k5 = z5;
i6 = x6*sin(t);
j6 = y6*cos(t);
k6 = z6;
i7 = x7*cos(t);
j7 = y7*sin(t);
k7 = z7;
i8 = x8*sin(t);
j8 = y8*cos(t);
k8 = z8;
// The Projection Matrix, increases or decreases the area of each polygon based on the z value
p1=i1*(k1+1);
q1=j1*(k1+1);
p2=i2*(k2+1);
q2=j2*(k2+1);
p3=i3*(k3+1);
q3=j3*(k3+1);
p4=i4*(k4+1);
q4=j4*(k4+1);
p5=i5*(k5+1);
q5=j5*(k5+1);
p6=i6*(k6+1);
q6=j6*(k6+1);
p7=i7*(k7+1);
q7=j7*(k7+1);
p8=i8*(k8+1);
q8=j8*(k8+1);
// The offset matrix, brings the vertices to the center of the window
a1= p1+350;
b1= q1+350;
a2= p2+350;
b2= q2+350;
a3= p3+350;
b3= q3+350;
a4= p4+350;
b4= q4+350;
a5= p5+350;
b5= q5+350;
a6= p6+350;
b6= q6+350;
a7= p7+350;
b7= q7+350;
a8= p8+350;
b8= q8+350;
// Draws the individual lines
line(a1,b1,a2,b2);
line(a2,b2,a3,b3);
line(a3,b3,a4,b4);
line(a4,b4,a1,b1);
line(a5,b5,a6,b6);
line(a6,b6,a7,b7);
line(a7,b7,a8,b8);
line(a8,b8,a5,b5);
line(a1,b1,a5,b5);
line(a2,b2,a6,b6);
line(a3,b3,a7,b7);
line(a4,b4,a8,b8);
delay(20);
cleardevice();
}}
getch();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
The Code for YZ Rotation
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <math.h>
int main()
{
float x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,x5,y5,z5,x6,y6,z6,x7,y7,z7,x8,y8,z8;
float i1,j1,k1,i2,j2,k2,i3,j3,k3,i4,j4,k4,i5,j5,k5,i6,j6,k6,i7,j7,k7,i8,j8,k8;
float p1,q1,p2,q2,p3,q3,p4,q4,p5,q5,p6,q6,p7,q7,p8,q8;
int a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7,a8,b8;
x1 = -100;
y1 = 100;
z1 = 0.2;
x2 = 100;
y2 = 100;
z2 = 0.2;
x3 = 100;
y3 = -100;
z3 = 0.2;
x4 = -100;
y4 = -100;
z4 = 0.2;
x5 = -100;
y5 = 100;
z5 = -0.2;
x6 = 100;
y6 = 100;
z6 = -0.2;
x7 = 100;
y7 = -100;
z7 = -0.2;
x8 = -100;
y8 = -100;
z8 = -0.2;
initwindow(700,700);
for( ; ; )
{
for (float t =0; t <= 2*3.14 ; t+=0.01)
{
i1 = x1;
j1 = y1*cos(t);
k1 = z1*sin(t);
i2 = x2;
j2 = y2*cos(t);
k2 = z2*sin(t);
i3 = x3;
j3 = y3*sin(t);
k3 = z3*cos(t);
i4 = x4;
j4 = y4*sin(t);
k4 = z4*cos(t);
i5 = x5;
j5 = y5*sin(t);
k5 = z5*cos(t);
i6 = x6;
j6 = y6*sin(t);
k6 = z6*cos(t);
i7 = x7;
j7 = y7*cos(t);
k7 = z7*sin(t);
i8 = x8;
j8 = y8*cos(t);
k8 = z8*sin(t);
p1=i1*(k1+1);
q1=j1*(k1+1);
p2=i2*(k2+1);
q2=j2*(k2+1);
p3=i3*(k3+1);
q3=j3*(k3+1);
p4=i4*(k4+1);
q4=j4*(k4+1);
p5=i5*(k5+1);
q5=j5*(k5+1);
p6=i6*(k6+1);
q6=j6*(k6+1);
p7=i7*(k7+1);
q7=j7*(k7+1);
p8=i8*(k8+1);
q8=j8*(k8+1);
a1= p1+350;
b1= q1+350;
a2= p2+350;
b2= q2+350;
a3= p3+350;
b3= q3+350;
a4= p4+350;
b4= q4+350;
a5= p5+350;
b5= q5+350;
a6= p6+350;
b6= q6+350;
a7= p7+350;
b7= q7+350;
a8= p8+350;
b8= q8+350;
line(a1,b1,a2,b2);
line(a2,b2,a3,b3);
line(a3,b3,a4,b4);
line(a4,b4,a1,b1);
line(a5,b5,a6,b6);
line(a6,b6,a7,b7);
line(a7,b7,a8,b8);
line(a8,b8,a5,b5);
line(a1,b1,a5,b5);
line(a2,b2,a6,b6);
line(a3,b3,a7,b7);
line(a4,b4,a8,b8);
delay(20);
cleardevice();
}}
getch();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
The Code for ZX Rotation
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <math.h>
int main()
{
float x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,x5,y5,z5,x6,y6,z6,x7,y7,z7,x8,y8,z8;
float i1,j1,k1,i2,j2,k2,i3,j3,k3,i4,j4,k4,i5,j5,k5,i6,j6,k6,i7,j7,k7,i8,j8,k8;
float p1,q1,p2,q2,p3,q3,p4,q4,p5,q5,p6,q6,p7,q7,p8,q8;
int a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7,a8,b8;
x1 = -100;
y1 = 100;
z1 = 0.2;
x2 = 100;
y2 = 100;
z2 = 0.2;
x3 = 100;
y3 = -100;
z3 = 0.2;
x4 = -100;
y4 = -100;
z4 = 0.2;
x5 = -100;
y5 = 100;
z5 = -0.2;
x6 = 100;
y6 = 100;
z6 = -0.2;
x7 = 100;
y7 = -100;
z7 = -0.2;
x8 = -100;
y8 = -100;
z8 = -0.2;
initwindow(700,700);
for( ; ; )
{
for (float t =0; t <= 2*3.14 ; t+=0.01)
{
i1 = x1*cos(t);
j1 = y1;
k1 = z1*sin(t);
i2 = x2*sin(t);
j2 = y2;
k2 = z2*cos(t);
i3 = x3*sin(t);
j3 = y3;
k3 = z3*cos(t);
i4 = x4*cos(t);
j4 = y4;
k4 = z4*sin(t);
i5 = x5*sin(t);
j5 = y5;
k5 = z5*cos(t);
i6 = x6*cos(t);
j6 = y6;
k6 = z6*sin(t);
i7 = x7*cos(t);
j7 = y7;
k7 = z7*sin(t);
i8 = x8*sin(t);
j8 = y8;
k8 = z8*cos(t);
p1=i1*(k1+1);
q1=j1*(k1+1);
p2=i2*(k2+1);
q2=j2*(k2+1);
p3=i3*(k3+1);
q3=j3*(k3+1);
p4=i4*(k4+1);
q4=j4*(k4+1);
p5=i5*(k5+1);
q5=j5*(k5+1);
p6=i6*(k6+1);
q6=j6*(k6+1);
p7=i7*(k7+1);
q7=j7*(k7+1);
p8=i8*(k8+1);
q8=j8*(k8+1);
a1= p1+350;
b1= q1+350;
a2= p2+350;
b2= q2+350;
a3= p3+350;
b3= q3+350;
a4= p4+350;
b4= q4+350;
a5= p5+350;
b5= q5+350;
a6= p6+350;
b6= q6+350;
a7= p7+350;
b7= q7+350;
a8= p8+350;
b8= q8+350;
line(a1,b1,a2,b2);
line(a2,b2,a3,b3);
line(a3,b3,a4,b4);
line(a4,b4,a1,b1);
line(a5,b5,a6,b6);
line(a6,b6,a7,b7);
line(a7,b7,a8,b8);
line(a8,b8,a5,b5);
line(a1,b1,a5,b5);
line(a2,b2,a6,b6);
line(a3,b3,a7,b7);
line(a4,b4,a8,b8);
delay(10);
cleardevice();
}}
getch();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////