## Introduction

You know that our **visual** world has three dimensions. Our eyes can determine the X,Y,Z axis of materials. Have you ever wondered we see the 3-Dimensiononal Images in the TV, Computer or etc. even though they're 2-Dimensional? How does happen?

It's a technique. In the fact in the 2-Dimensional images, there is a function that converts the **(x,y,z) set** to the **(x,y) set**. This means that in the new set, the **x,y** axis is related to the **x,y,z** in the old set. Sure you see the 3D games and even the movies, you see them in the 2D TV or LCD although they're 3-Dimensional. We almost can say that is the **Foundation** of the 3D Engine and even the **OpenGl** or etc. This means that we can make and design such things. Also we can use this algorithm for simulating the sets, labs, and ideas. That's why it can reduce time and cost. In this article we'll check these events.

## Background

To get the the most from this subject you should read or search about 3Dimension. As a base, you need to know mathematical relations and functions.

## Aalgorithm

In fact the base of this article is math. That means we have to find the suitable relations to convert the three dimension to the two dimension. Let's start.

To realize this matter, first we work on the chart and 2D. First of all put the virtual axis front of your eyes. Imagine the point **q (1,1)** in 2D set. You know that's equivalent the point **p (1,1,0)** in the 3D set. After that we want plus the value of **Z** of **p** and set **p (1,1,1)**. Now imagine the point **p** . You see that far away from axis center and that's more up and right, although that still has position **(x,y)=(1,1)**. Whatever you increase the value of **Z** you see the point **p** is going more up and right side. Next set the **p(1,1,-1)**. You sure see the point **p** is nearing to the axis center and that is a little less than **X,Y** in the 2D set. And whatever you decrease the value of **Z** like -extreme, the point **p** is going to the axis center. You can test it with real materials.

So we find out the **X,Y** in 2D set are related to the **Z** in 3D set. Like below chart :

Look at these real images and compare the them with the chart :

So here are thefunctions to get this chart :

sgn(z)
X in 2D set = f(x,y,z) in 3D set = x * | (z + sgn(z)) |
sgn(z)
Y in 2D set = f(x,y,z) in 3D set = y * | (z + sgn(z)) |

These are true when the axis center is

**(0,0)** And when we want to have global function and draw the

**(x,y,z)** with

**(xo,yo,zo) axis center** we find these functions:

sgn(z)
X in 2D set = f(x,y,z) in 3D set = xo + x * | (z + sgn(z)) |
sgn(z)
Y in 2D set = f(x,y,z) in 3D set = yo + y * | (z + sgn(z)) |

We can adjust the focus of camera. To do this adjust lens of camera. We Dim :

zm = z / lens
sgn(zm)
X in 2D set = f(x,y,z) in 3D set = xo + x * | (zm + sgn(zm)) |
sgn(zm)
Y in 2D set = f(x,y,z) in 3D set = yo + y * | (zm + sgn(zm)) |

To use these functions we have to write these in the OnPaint() event. The above functions used to draw and display the vertex from 3D set to 2D set. And to rotate the point **p(x,y,z)** around it's center **po(xc,yc,zc)** we have below three states. Attend these are used to 3D set.

1_ Turning the point around **Z axis**, that means the **X,Y** are rotating and **Z** is constant. use this function :

x = (x - xc) * cos(teta) - (y - yc) * sin(teta) + xc
y = (x - xc) * sin(teta) + (y - yc) * cos(teta) + yc

2_ Turning the point around

**Y axis**, that means the

**X,Z** are rotating and

**Y** is constant. use this function :

z = (z - zc) * cos(teta) - (x - xc) * sin(teta) + zc
x = (z - zc) * sin(teta) + (x - xc) * cos(teta) + xc

3_ Turning the point around

**X axis**, that means the

**Z,Y** are rotating and

**X** is constant. use this function :

z = (z - zc) * cos(teta) - (y - yc) * sin(teta) + zc
y = (z - zc) * sin(teta) + (y - yc) * cos(teta) + yc

## Using the code

To dismount above relations we need to code those. First of all declaration an object of

**3D Point** and then declaration an array of that for a quad's vertices. So this is structure of 3D point :

class three_dimension_point{
public:
three_dimension_point();
void SetPoint(float x,float y,float z);
float x,y,z; //coordinates
float xc,yc,zc; //center of the point. it used to rotation
void XY(int t);
void XZ(int t);
void ZY(int t);
};
three_dimension_point::three_dimension_point(){
x=y=z=xc=yc=zc=0;
}
void three_dimension_point::SetPoint(float X,float Y,float Z){
x=X;y=Y;z=Z;
}
void MoveX(int t){
for(char i=0;i<=24;i++){
point[i].x+=t;point[i].xc+=t;
}
}
void MoveY(int t){
for(char i=0;i<=24;i++){
point[i].y+=t;point[i].yc+=t;
}
}
void MoveZ(int t){
for(char i=0;i<=24;i++){
point[i].z+=t;point[i].zc+=t;
}
}
void RotX(int t/*degree*/){//around x axis
float teta=t*pi/(float)180;
for(char i=0;i<24;i++){
float c=cos(teta),s=sin(teta);//use once these functions to reduce calculating
float zt=(point[i].z-point[i].zc)*c-(point[i].y-point[i].yc)*s+point[i].zc;
float yt=(point[i].z-point[i].zc)*s+(point[i].y-point[i].yc)*c+point[i].yc;
point[i].z=zt;
point[i].y=yt;
}
}
void RotY(int t/*degree*/){//around y axis
float teta=t*pi/(float)180;
for(char i=0;i<=24;i++){
float c=cos(teta),s=sin(teta);//use once these functions to reduce calculating
float zt=(point[i].z-point[i].zc)*c-(point[i].x-point[i].xc)*s+point[i].zc;
float xt=(point[i].z-point[i].zc)*s+(point[i].x-point[i].xc)*c+point[i].xc;
point[i].z=zt;
point[i].x=xt;
}
}
void RotZ(int t/*degree*/){//around z axis
float teta=-t*pi/(float)180;
for(char i=0;i<=24;i++){
float c=cos(teta),s=sin(teta);//use once these functions to reduce calculating
float xt=(point[i].x-point[i].xc)*c-(point[i].y-point[i].yc)*s+point[i].xc;
float yt=(point[i].x-point[i].xc)*s+(point[i].y-point[i].yc)*c+point[i].yc;
point[i].x=xt;
point[i].y=yt;
}
}

In the

`OnPaint()`

event we draw the points ans axis coordinates. To see the object in the scene we draw line

**(edge)** between every vertices.

float zm,xn,yn;
for(int i=0;i<23;i++){ zm=yn=xn=0;
zm=point[i].z/(float)lens;
float d=abs(pow(zm+sgn(zm),sgn(zm)));
xn=xo+(point[i].x)*d;
yn=yo-(point[i].y)*d;
dc.MoveTo(xn,yn);
i++;
zm=yn=xn=0;
zm=point[i].z/(float)lens;
d=abs(pow(zm+sgn(zm),sgn(zm)));
xn=xo+(point[i].x)*d;
yn=yo-(point[i].y)*d;
dc.LineTo(xn,yn);
}

Of course, to use this more easily we make buttons on the scene and put for theme rectangles and their corresponding code. In the

`OnInitDialog()`

event we set first value and initial the button's area. And in the

`Timer()`

we do automatically repaint the scene.

## Points of Interest

It passed about four years ago when I wrote these algorithm. But it's funny that I became dizzy at looking what I wrote and what trying to figure out what it meant! Also my handwriting is not that great. Sometimes so bad that I can't read it myself!