# A basic 3d to 2d projection

Developing an actual 3D engine is an incredible amount of work, and including a 3D library in your project can add a considerable amount of bloat to your project. Fortunately you can implement some very simple 3D projections in just a couple of lines of code, and they are not computationally intensive. There are limitations on using this particular method though:

• This can draw wire frames only.
• You need all of the coordinates of your “world” to be centered horizontally and vertically relative to your screen (or you need to convert them to be that way).
• All of the lines must fit on the screen (e.g. you can’t have the edge of an object partially off-screen)

The basic algorithm is incredibly simple. For each given point (x,y,z) in your 3D model, you convert it to 2D screen coordinates (x’,y’) by the following equations:

```x'=d*x/z
y'=d*y/z
```

Where (x,y,z) are the points in your 3D world, (x’,y’) are the x,y coordinates from the center of your screen. And d is the focal length of the camera (or scaling factor), if you’re not sure what to use you can get good results just by experimenting.

Below is C# code to demonstrate this concept. Notice that most of the code is for manipulating, offsetting, and scaling the box, the actual code projecting to 2D is only two lines.

```        protected override void OnPaint(PaintEventArgs e)
{
float[]  box = {
-1,-1,0,
1,-1,0,
1,1,0,
-1,1,0,
-1,-1,0,
-1,-1,2,
1,-1,2,
1,-1,0,
1,-1,2,
1,1,2,
1,1,0,
1,1,2,
-1,1,2,
-1,1,0,
-1,1,2,
-1,-1,2
};
base.OnPaint(e);

float scale = .2f;
for (int x = 0; x < box.Length; x++) box[x] *= scale;

for (int j = 0; j < 10; j++)
{
for (int k = 0; k < 10; k++)
{
float zoffset = 10f;
float xoffset = 1f*(j-5);
float yoffset = 1f*(k-5);

float d = 500;
float lastX = d * (box[0] + xoffset) / (box[2] + zoffset);
float lastY = d * (box[1] + yoffset) / (box[2] + zoffset);

Pen p = new Pen(new SolidBrush(ForeColor));
int i = 3;
while (i < box.Length)
{
float x = d * (box[i + 0] + xoffset) / (box[i + 2] + zoffset);
float y = d * (box[i + 1] + yoffset) / (box[i + 2] + zoffset);
e.Graphics.DrawLine(p, translate(new PointF(lastX, lastY)), translate(new PointF(x, y)));
lastX = x;
lastY = y;

i += 3;
}
}
}

}

private PointF translate(PointF p)
{
PointF f = new PointF(p.X+this.Width/2, p.Y+this.Height/2);
return f;
}
}
```

This is a very useful technique for drawing diagrams and simple objects, and can be a starting point for adding more features like rotation, or solids.