Author Topic: AXECUBE Example  (Read 1274 times)

0 Members and 1 Guest are viewing this topic.

Offline boltmanguy

  • LV0 Newcomer (Next: 5)
  • Posts: 2
  • Rating: +0/-0
    • View Profile
AXECUBE Example
« on: June 10, 2015, 12:52:52 pm »
I've been removed from calculator programming for a while now, back in highschool I used to make a bunch of crazy stuff, but I was never able to understand how the 3D AXECUBE example program actually worked and the documentation never really explained much of what was going on there so now, years later, I'm still curious.
So if anyone knows how it works and would be kind enough to explain it in some pretty good detail it'd be much appreciated. :3

Offline Haobo

  • LV2 Member (Next: 40)
  • **
  • Posts: 27
  • Rating: +4/-0
    • View Profile
Re: AXECUBE Example
« Reply #1 on: June 16, 2015, 01:21:20 am »
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 :P



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 :P )

POINTS
First 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:

Code: [Select]
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.

CAMERA
Now 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.

DISPLAY
Now 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.

Code: [Select]
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:

Code: [Select]
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:



TRANSFORMATIONS
We will discuss only rotation though, cause that’s all I know well :P . 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:

Code: [Select]
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:

Code: [Select]
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. :P
Here’s the final design!




LINES/FACES
Lines 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:

Code: [Select]
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 CULLING
If anyone wants it

Offline boltmanguy

  • LV0 Newcomer (Next: 5)
  • Posts: 2
  • Rating: +0/-0
    • View Profile
Re: AXECUBE Example
« Reply #2 on: June 17, 2015, 01:07:37 pm »
Heyyy, thanks for all the info, while not exactly what i was looking for it was still really nice. I've never been able to find a simplleee explanation or demonstration of how to take 3d points and flatten them to a 2d screen and there you showed it in just a few computations.

I kinda trailed off at the bit on rotation because the explantion there wasnt great and no code to follow but a after a little searching online i found a solution to x,y,z axis rotation thats quite simple. After i got all the working i even did a little bit of research into backface culling and implemented it into my silly script.

Not sure why but i decided itd be pretty silly to write this in C# for unity3d, which is already a 3d engine anyway, so i obviously called my script meta 3d.
Heres short video of what i did with my experiments, and some backface culling at the end.
https://www.youtube.com/watch?v=ONHY9_PaGxI