3D Points to 2D Points
There is no direct way to convert a point in 3D space into a 2D point simply because that does not make any sense. In order to convert between spaces we need to know from where we are looking at the 3D point. For that we'll need two values, the camera's Z position and the zoom.
To calculate the zoom I found using the monitor's width gives a pretty "square" 3D drawing. (Less distortion in other words)
double zoom = (double)Screen.PrimaryScreen.Bounds.Width / 1.5;
So with the zoom we can now calculate the camera's Z position. For this example, I use the cube's top right point and the cube's center as a reference in order the keep the camera at the same relative distance. That prevents the cube from looking like it is getting smaller and bigger when it rotates.
Math3D.Point3D anchorPoint = (Math3D.Point3D)cubePoints[4]; //anchor point
double cameraZ = -(((anchorPoint.X - cubeOrigin.X) * zoom) / cubeOrigin.X) + anchorPoint.Z;
Math3D.Camera camera1 = new Math3D.Camera();
camera1.Position = new Math3D.Point3D(cubeOrigin.X, cubeOrigin.Y, cameraZ);
Now, with perspective values, we are ready to take our 3D points and get a simple (X, Y) value out of them. Cold, hard math here, if you can understand it that is good, if not just go with it.
//Assume
//----------
//point3D is a Point3D object with values X, Y, and Z
//camera1 is a Camera object with a Point3D Position value
//drawOrigin is a Point that represents the center of where the cube will be drawn
//cubeOrigin is the middle of the cube in 3D spaces (width / 2, height / 2, depth / 2)
Point point2D = new Point();
if (point3D.Z - camera1.Position.Z >= 0)
{
point2D.X = (int)((double)-(point3D.X - camera1.Position.X) / (-0.1f) * zoom) +
drawOrigin.X;
point2D.Y = (int)((double)(point3D.Y - camera1.Position.Y) / (-0.1f) * zoom) +
drawOrigin.Y;
}
else
{
Point tmpOrigin = new Point();
tmpOrigin.X = (int)((double)(cubeOrigin.X - camera1.Position.X) / (double
(cubeOrigin.Z - camera1.Position.Z) * zoom) + drawOrigin.X;
tmpOrigin.Y = (int)((double)-(cubeOrigin.Y - camera1.Position.Y) / (double)
(cubeOrigin.Z - camera1.Position.Z) * zoom) + drawOrigin.Y;
float x = (float)((vec.X - camera1.Position.X) / (point3D.Z - camera1.Position.Z) *
zoom + drawOrigin.X);
float y = (float)(-(vec.Y - camera1.Position.Y) / (point3D.Z - camera1.Position.Z) *
zoom + drawOrigin.Y);
point2D.X = (int)x;
point2D.Y = (int)y;
}
Math3D.Point3D[] verts = new Math3D.Point3D[24];
//front face
verts[0] = new Math3D.Point3D(0, 0, 0);
verts[1] = new Math3D.Point3D(0, height, 0);
verts[2] = new Math3D.Point3D(width, height, 0);
verts[3] = new Math3D.Point3D(width, 0, 0);
//back face
verts[4] = new Math3D.Point3D(0, 0, depth);
verts[5] = new Math3D.Point3D(0, height, depth);
verts[6] = new Math3D.Point3D(width, height, depth);
verts[7] = new Math3D.Point3D(width, 0, depth);
//etc... (rest of code can be downloaded)
We will use this array of points later when we want to rotate the cube, but for now they are ready to be drawn. The drawing has no real trick to it; the lines just have to be drawn in the correct order:
//Back Face
g.DrawLine(Pens.Black, point3D[0], point3D[1]);
g.DrawLine(Pens.Black, point3D[1], point3D[2]);
g.DrawLine(Pens.Black, point3D[2], point3D[3]);
g.DrawLine(Pens.Black, point3D[3], point3D[0]);
//Front Face
g.DrawLine(Pens.Black, point3D[4], point3D[5]);
g.DrawLine(Pens.Black, point3D[5], point3D[6]);
g.DrawLine(Pens.Black, point3D[6], point3D[7]);
g.DrawLine(Pens.Black, point3D[7], point3D[4]);
//Right Face
g.DrawLine(Pens.Black, point3D[8], point3D[9]);
g.DrawLine(Pens.Black, point3D[9], point3D[10]);
g.DrawLine(Pens.Black, point3D[10], point3D[11]);
g.DrawLine(Pens.Black, point3D[11], point3D[8]);
//Left Face
g.DrawLine(Pens.Black, point3D[12], point3D[13]);
g.DrawLine(Pens.Black, point3D[13], point3D[14]);
g.DrawLine(Pens.Black, point3D[14], point3D[15]);
g.DrawLine(Pens.Black, point3D[15], point3D[12]);
//Bottom Face
g.DrawLine(Pens.Black, point3D[16], point3D[17]);
g.DrawLine(Pens.Black, point3D[17], point3D[18]);
g.DrawLine(Pens.Black, point3D[18], point3D[19]);
g.DrawLine(Pens.Black, point3D[19], point3D[16]);
//Top Face
g.DrawLine(Pens.Black, point3D[20], point3D[21]);
g.DrawLine(Pens.Black, point3D[21], point3D[22]);
g.DrawLine(Pens.Black, point3D[22], point3D[23]);
g.DrawLine(Pens.Black, point3D[23], point3D[20]);