Guess I'll help out, but this is
very very long, and probably boring, but if you want to actually learn how to do it, read on. Most of this is just what I learned from
matref's contest entry anyway, just in a form I find better than on a calculator
Just note, I don't write much tutorials, so it won't be real high quality, but I will try to explain most concepts. Note, all points will be (X,Y,Z) for simpler graphing. (Plus, everything is not optimized, and I provide no actual code, only concepts since I deleted the code a while ago
)
POINTSFirst of all, the main idea is points. In simple 3D rendering, you need to define certain points that will be displayed. These will just be imagined in your own mind, or planned out. A simple cube though, is pretty easy.
These are the points I will use:
Data(10^^r,10^^r,10^^r)
Data(10^^r,10^^r,~10^^r)
Data(10^^r,~10^^r,10^^r)
Data(10^^r,~10^^r,~10^^r)
Data(~10^^r,10^^r,10^^r)
Data(~10^^r,10^^r~10^^r)
Data(~10^^r,~10^^r,10^^r)
Data(~10^^r,~10^^r,~10^^r)
These points are made to display a standard cube. You can probably imagine that it is surrounding the origin of (0,0,0), with side lengths of 20 units.
CAMERANow that the points are established, we need to also establish a camera, which will be offset from the coordinates of the cube. You can probably guess that everything will be displayed from the camera. More importantly, it is removing the distance Z from everything to right in front of the camera, which will make X and Y the screen. For our case, I will place it at (0,0,~50). This way, you will be viewing the cube from a distance of 50 units away. In the code, the coordinate variables of the camera will be in Xcam, Ycam, and Zcam respectively.
DISPLAYNow since we established both the camera and the points, we can now display then on a screen! For the monochrome, the length of the X screen and Y screen are 96 pixels and 64 pixels. In order to convert 3D points to 2D points, the basic idea is to eliminate one plane, for us, we are eliminating the z plane. Now, it may seem to be hard, but with some simple calculations, it's extremely simple. The variables for each point coorinate, looping, is Zcoord, Ycoord, and Xcoord.
Here’s the code to do it.
Zcoord-Zcam->Z
(Xcoord-Xcam)*64/Z+48->X
(Ycoord-Ycam)*64/Z+32->Y
(Zcoord-Zcam*64/Z
That’s all there is. Now, know that you need to do this for every single point. I’ll also try to explain the code in more detail.
All of the coordinates need to be subtracted from the camera coordinates to get everything relative to the camera, or else they will be relative to the origin, (0,0,0).
The X and Y are then multiplied by 64, which can really be any number, but that’s a good scale to use for now. The values are then divided by Z. This basically eliminates the Z plane from the 3D display. That’s the basis of 3D projection. If you look at the last line of the code, the Z is basically divided by itself, which makes it a constant value, if done the same equation. Thus, you don’t even need the Z!
X and Y have a constant added to them because of the offset of the calculator screen. Since the origin (0,0) of the screen is the top left, we add the center of the screen points so that (0,0) is at the center. This depends on the size of the screen and where you specify (0,0).
So this would be our code:
For(Vertices,0,7)
Zcoord-Zcam->Z
(Xcoord-Xcam)*64/Z+48->X
(Ycoord-Ycam)*64/Z+32->Y
Pxl-On(X,Y)
End
Here’s the result:
TRANSFORMATIONSWe will discuss only rotation though, cause that’s all I know well
. To rotate the 3D space, first lets set down 3 more variables, Xrot, Yrot, and Zrot. All of these are angles that can be rotated based on the X, Y, and Z planes. Now, I won’t actually tell you the matrix, you can look for that online in multiple
websites. Instead, I will just go through the X rotation only. This is the general equation:
Ycoord*cos(Xrot)-Zcoord*sin(Xrot)->Y
Ycoord*sin(Xrot)+Zcoord*cos(Xrot)->Z
That’s it! Now, I don’t actually understand the math behind it, but you can definitely look up why this works. Either way, this will change the point in 3D space based on X, which the Y and Z changing. This output will then be thrown into the display equation the same way, and that will give the image of a rotation.
Here’s the simple code of combining the formulas:
For(Vertices,0,7)
(Ycoord*sin(Xrot))-(Zcoord*cos(Xrot))-Zcam->Z
(Xcoord-Xcam)*64/Z+48->X
((Ycoord*cos(Xrot))+(Zcoord*sin(Xrot))-Ycam)*64/Z+32->Y
Pxl-On(X,Y)
End
Now this is completely unoptimized, but this shows you just how simple it is to replace the values of Y and Z with the transformed coordinates.
This is a result of that code, with some getKeys so that the rotation can move. Now also note that I tried to avoid axe specific syntax, so you can read it better.
Here’s the result:
(jstified’s glitch)
Now that’s just for the X rotation. There are also rotation equations for Y and Z, but it all matters about which one you do first. Doing the equation for X, then Y, then Z, is different that the one for Y, then X, then Z. There are also general rotation matrices that people have calculated using each individual matrices. Here’s the one for X, then Y, then Z.
Just create an equation out of it, I had one, lost it, don't wanna redo it.
Here’s the final design!
LINES/FACESLines are just as simple as dots. All you need to do is connect the dots to make lines. The hard part is connecting them in the right order.
Basically, this is very simple as well. The coordinates we put in the points section are in an order. That order is what we’ll use to figure out where the lines are. First, let’s change the code that that when displaying the vertices, it will display numbers instead:
Now that there’s numbers, you can create lines out of them! But it also might be better to do faces instead. Instead of just connecting lines, you can connect faces together, which is also needed for backface culling, which makes the 3D object actually look 3D. But that’s for the next part. So we’ll group them into faces. By looking at the gif, you can divide the faces into parts, like this:
Data(0,1,3,2)
Data(0,2,6,4)
Data(0,4,5,1)
Data(1,5,7,3)
Data(2,3,7,6)
Data(4,5,7,6)
Now know that I organized the faces in counter clockwise order by putting the vertices of each face in the array of data. Now, to display the faces, you need to loop through each one of them and draw lines from one coordinate to the other, which you have if you stored the X and Y transformed and projected points.
This part of the code would be different for each language, but it shouldn’t be too hard to loop through the faces and vertices.
Here’s an example.
BACKFACE CULLINGIf anyone wants it