Pygame DIY 3D Graphics - Part 1: Theory
In order to successfully display 3D graphics, you need to convert 3-dimensional coordinates into 2-dimensional coordinates, to go on screen. Before we start, I'd like to make it clear that coordinates x, y, z refer to width, height and depth respectively. As an example, if your screen was of size 1980x1080, and you wanted to display a 3D point (0,0,z1) relative to the camera, the 2D pixel coordinates would be (990,540), the middle of the screen, assuming any value for z1 > 0. This blog will describe the theory behind an algorithm to convert 3D coordinates to 2D coordinates.
The picture above demonstrates a method of achieving this. This technique involves imagining that the computer screen is in the 3D space that is trying to be simulated. The screen is represented as the blue rectangle in the x-y plane. The red dot is imagined to be the eye of the user - we have given it coordinates of (0,0,-20). In order to display the green dot, which has coordinates (20,30,50) we can draw a straight line from the green dot to the red dot, shown by the dotted line. This line intersects the screen when the z value of zero. Ignoring this z value leaves us with 2D coordinates of (5.7,8,5).
How is this calculated? Maths. We can obtain the x-value by looking only at the z-x plane and ignoring all y values. Then use the gradient, point coordinates and the formula z - pz = m(x - px) to obtain a value for x, when z = 0, where m is the gradient and px, pz are the coordinates of either the 'eye' or the 3D point. The same can now be done with the formula y - py = m(z - pz) to find the y value.
Hence we have calculated 2D pixel coordinates of a 3D point.
What if we want to move the camera? Translating the camera through 3D space is easy - just before the calculation, the coordinates of camera are subtracted from the coordinates of the point. To rotate the camera, we apply the rotation matrix:
Rotation first takes place about the y axis. Instead of rotating the camera, the points rotate about the camera. Hence the 3D coordinates are manipulated:
x = x*cos(α) - z*sin(α) z = z*cos(α) + oldx*sin(α)
Where α is the angle of rotation. We must be careful to use the original value of x in out calculation of z. Now, the same is done about the x axis.
y = y*cos(α) - z*sin(α) z = z*cos(α) + oldy*sin(α)
The same can be done about the z axis for camera tilt, but it is not necessary.
The next part will focus on applying this theory to code.