Remade with triangles and some (almost) good lighting.
Below is somewhat lengthy derivation. I'll make it more clear later.
And of course, there are still some issues with the program (the rotation doesn't work as intended, and I haven't figured out how to zoom yet).
Let's try to create a 3D scene on screen, doing it from scratch, and using only a 2D renderer (macroquad in this case).
First, we figure out the most simple case of a fixed camera.
From the diagram we can see that
On the other hand:
But it's better to use acos instead of atan, because we won't have to deal with division by zero.
So we have:
Or, for the coordinates on screen:
There also should be clear order of rendering, because otherwise we'll see far-away objects through the ones that are closer to us.
Since this version of the program works with triangles, we are going to order them according to the distance between midpoint and the camera.
So for this case, if we want to render a points, all we need to do is to start its data:
And then calculate its on-screen coordinates according to:
To figure out the moving camera, we have to actually change the origin for our coordinate system.
First, let's shift x and z axes by r as shown here:
Now we have to replace all the y coordinates in the previous formulas by:
This is going to be our camera's defaut position. But what happens if we rotate our coordinates around the new z axis?
Let's look at the picture.
For this kind of rotation we'll actually need to use the rotation matrix, but we'll just write down the final formulas:
Start with:
And then calculate the on-screen coordinates according to:
We'll also need to define according to screen size:
We should put
where
We also need to ensure that:
Otherwise, the objects are not in the field of view and shouldn't be rendered.
To account for rotation in both directions, we have to compose two rotaions:
And:
For the lighting, we create a point source, and then derive the intensity from scalar product of two vectors: the path between light source and the midpoint of a triangle, and the normal vector of the triangle.
Still need to figure out how to account for the shade.