Computer Science Canada [Tutorial] 3D graphics 
Author:  Windsurfer [ Mon Oct 16, 2006 9:14 pm ]  
Post subject:  [Tutorial] 3D graphics  
I have written this as more a discussion with myself... or towards an imaginary person. Not really a "tutorial" wording. Okay, so there comes a point in a programmers course (once we learn graphics) that we sit down and think, "I should make something awesome. Something mind blowing. Something... threeDee!!!" *cough* okay, well, at least i did. Of course, then you wonder... how can you draw 3D? Draw.Line only accepts things in 2D.... hrm. Well, what you could do, is visualise the screen as a window (well, at least that's what i did) and realise that what you see in the window is simply a representation of a 3D world. So, if you think of what you have been drawing in 2D as simply the "glass" on this window, then the new dimension would be the axis going into and coming out of the screen. But how do you get your monitor to draw that axis? Well, obviously, you can't directly . So you figure out how this new dimension related to your screen. When you look at the real world, everyone knows that as objects get further from you, they appear to diminish in size. The amount they get smaller, one may have noticed, is not linear, meaning if an object goes x distance from you, it will not be x size. Instead something else happens. If an object moves z amount away from you, it will appear 1/z (that's one divided by zed). Let me explain in detail. If you were to draw a ball (okay, a circle) at point x,y on the screen, you would simply use some code that expresses how do draw this ball. Eg.
Now, what that does should be fairly obvious. It draws a circle at (x,y) or 100,100. Now, what we really want to do here is draw a ball at... say... (100,100,10). That 10 would be the z coordinate. Well, it's quite simple to figure out where the ball would be on the screen, actually. It's really basically dividing the x and y coordinates by the z coordinate. Surprised? All this talk about 3D and that's it? Sort of. Well, yes, but more like that's the foundation.... well, you'll see. So you start off with this. You apply this new idea to drawing the ball, and you can find that you can make a procedure that can spit out the x and y coordinates.
Well, cool. Now lets draw the ball at 100,100,10 10 is the new axis, the z cooridinate.
Notice how i made the size2D function by simply dividing the size by the z coordinate. It's actually the same idea. Now, you may be thinking it's not that great... well, visually it's not. Yet. Let's add some control to it to make it more interesting.
Whoa! What just happened? Well, i simply made the x and y coordinates of the ball the same as the mouse... and I made the z coordinate a variable that is controlled with the mouse buttons. That's all. Can you see how it's 3D now? This is just the beginning. I will folow up with drawing a cube later. 
Author:  Cervantes [ Tue Oct 17, 2006 9:09 am ]  
Post subject:  
Nice, Windsurfer! The style of the tutorial is good. The most important thing with tutorials is that they are A) correct and B) easy to read. There are many different ways of achieving B), and you've got one of them. One comment: Your make3D "procedure" should really be a function.
That kind of blatant sideeffect is just frightening to me. Instead,
You'll notice I also changed the function name to "make2D", as I think that's a better reflection of what we're doing. I also used reals to represent the coordinates returned by the function, to allow for better accuracy. These values can be rounded when drawing. 
Author:  Windsurfer [ Tue Oct 17, 2006 3:29 pm ] 
Post subject:  
I actually tried to keep the coding as dumbed down as possible... without getting into any horrible coding practices. Admittedly, a record in that situation works very well, however, it may confuse a lot of beginners. And yes, i did mislabel that procedure... I'm going toi change it now. 
Author:  Cervantes [ Tue Oct 17, 2006 4:35 pm ] 
Post subject:  
I think it reasonable to assume that anyone wishing to tackle 3D graphics has types under their belt. And I mean the sane people wishing to tackle 3D graphics. There's a lot of noobs who would want to tackle 3D graphics before even learning 2D. Besides, creating procedures that modify the values of the variables you give them is a horrible coding practice. Sure, it works, but it only works because you wrote that procedure, and you know exactly how it manipulates the variables. If someone wants to use your subroutine, that someone has to also know exactly how it manipulates the variables it's given. He wouldn't want to use your procedure because he's unsure of what awful things your procedure might do to his precious variables. A function, however, doesn't modify the state of the program. Instead, it computes new values. This last statement is fundamental to functional programming (not programming with functions in Turing, but the paradigm itself  programming in languages like LISP, Scheme, O'Caml, and Haskell). In pure functional languages, we don't even have variables. That might seem like it'd be a bad thing, but it's not, since functional languages are based on the computation of new values instead of the modification of old values. 
Author:  Clayton [ Tue Oct 17, 2006 4:41 pm ] 
Post subject:  
Well really, a beginner shouldnt really be going straight into 3D graphics, so I personally, would keep the coding as neat and tidy as possible. Some tips:
Perhaps a Beginner, Intermediate, Advanced sort of level Tutorial would be good too So far though, good stuff! EDIT: DOH! Cervantes beat me to it, ^^What he said^^ 
Author:  [Gandalf] [ Tue Oct 17, 2006 5:52 pm ] 
Post subject:  
Freakman wrote: ^^What he said^^
And yet you and he said two completely different things. O_o Cervantes wrote: Besides, creating procedures that modify the values of the variables you give them is a horrible coding practice. Sure, it works, but it only works because you wrote that procedure, and you know exactly how it manipulates the variables. If someone wants to use your subroutine, that someone has to also know exactly how it manipulates the variables it's given. He wouldn't want to use your procedure because he's unsure of what awful things your procedure might do to his precious variables. A function, however, doesn't modify the state of the program. Instead, it computes new values.
Definately an understandable point, but then, you're saying that passing by reference is always horrible coding practice? Hrm? Or is it just that it doesn't follow the model behind functional programming... 
Author:  zylum [ Tue Oct 17, 2006 6:19 pm ] 
Post subject:  
doh! i was actually in the process of writing a 3d tutorial windsurfer > all but your second code snippet have errors / warnings. 
Author:  Cervantes [ Tue Oct 17, 2006 6:53 pm ] 
Post subject:  
[Gandalf] wrote: Cervantes wrote: Besides, creating procedures that modify the values of the variables you give them is a horrible coding practice. Sure, it works, but it only works because you wrote that procedure, and you know exactly how it manipulates the variables. If someone wants to use your subroutine, that someone has to also know exactly how it manipulates the variables it's given. He wouldn't want to use your procedure because he's unsure of what awful things your procedure might do to his precious variables. A function, however, doesn't modify the state of the program. Instead, it computes new values.
Definately an understandable point, but then, you're saying that passing by reference is always horrible coding practice? Hrm? Or is it just that it doesn't follow the model behind functional programming... Allowing subroutines the ability to modify the values of the variables you give them is horrible. This is a concept that is strictly forbidden in pure functional programming languages. But that's not the reason I condemn it in Turing. I condemn it in Turing because it is a terrible idea to give so much of your control away. I want to clarify with you: [Gandalf] wrote: you're saying that passing by reference is always horrible coding practice
Are you referring to passing a variable to a subroutine as we usually do (passing the value of the variable as an argument such that the parameters within the subroutine become that value) or are you referring to actually giving the memory address of the variable to the subroutine so the subroutine can go ahead and butcher that location in memory if it wants to? zylum wrote: doh! i was actually in the process of writing a 3d tutorial
See, this is why you should all coordinate in the Improving Tutorials thread. 
Author:  Windsurfer [ Tue Oct 17, 2006 7:19 pm ] 
Post subject:  
D'Oh! i hate that... supid C programming... and i thought i checked everything... And about this function thing... Weird, my programming teacher is pushing passing pointers. He would rather we had functions modify those, and return an int for error checking. (Maybe that's just a C thing?) And I'm sorry I did this tutorial before you... perhaps i could see what you have written/done so far, and we could collaberate? 
Author:  [Gandalf] [ Tue Oct 17, 2006 7:20 pm ] 
Post subject:  
Cervantes wrote: I want to clarify with you:
[Gandalf] wrote: you're saying that passing by reference is always horrible coding practice
Are you referring to passing a variable to a subroutine as we usually do (passing the value of the variable as an argument such that the parameters within the subroutine become that value) or are you referring to actually giving the memory address of the variable to the subroutine so the subroutine can go ahead and butcher that location in memory if it wants to? The latter, of course. Yes, there is the potential for unsafe/unpredictable code, but that doesn't change the fact that it's useful on occassion, right? Or is it completely pointless and should be avoided at all costs? Meh, I don't really have anything else to say, but it just surprised me that you would completely condemn such a... key ability in programming languages. 
Author:  Cervantes [ Tue Oct 17, 2006 8:30 pm ] 
Post subject:  
[Gandalf] wrote: Meh, I don't really have anything else to say, but it just surprised me that you would completely condemn such a... key ability in programming languages.
A key ability? What does this approach offer that functions (returning user defined types if necessary) do not? 
Author:  Danjen [ Wed Nov 22, 2006 11:32 am ] 
Post subject:  Wait a minute 
Hold on, I'm kind of a noob in turing, and I was wondering, why would you use functions as opposed to procedures, and why would you use records. Also, what should / would variable Z be set to in the previous program? 
Author:  Cervantes [ Wed Nov 22, 2006 2:36 pm ] 
Post subject:  
Much of the time we write subroutines to compute a value from some given values. We might, for example, write a subroutine to compute somebody's taxes. It makes sense to use a function for this. The value returned by the function is the amount of tax owed. On the other hand, using a procedure makes no sense, because it doesn't return a value. Instead, you'd have to directly output the value, which makes the procedure kind of silly, because you never really know what the taxes owed are. The only way you could know is if you're looking at the output screen. Your program certainly doesn't know. But it could know, using procedures, if you allow the procedure to modify some global variables. This has two problems: first, if the procedure can modify that global variable that represents tax owed by person A, how much more power does it have? What's to stop it from modifying other global variables? It could ruthlessly change the state of a program. Second, while coding, we have to distinctly remember what variable is being changed by the procedure, then refer to it. There's none of that confusion with functions. Using records is often a good idea because it groups data that should be grouped. For example, consider having a bunch of points. Each point has an x and y component. We could use two arrays, each of length n, one for x values and one for y values. However, this is messy. When working with this, we have to assume that the i'th element of the x array and the i'th element of the y array are supposed to go together. What if things get out of order? Using records allows us to have a single array of points, where each point has an x and y value. No confusion here. 
Author:  Wolf_Destiny [ Wed Nov 22, 2006 3:34 pm ] 
Post subject:  
Since this thread got bumped... ...I've been making a 3d game  or at least the engine for it. I've got heightmaps, walkable zones and room boundaries. Different polygon types (character and terrain) and external model files. Since it also have rotation I needed a sorting algorithm. The one I'm using (a rough approximation of the Painter's Algorithm (or depth sorting)) isn't working very well for me; at all. I've seen programs with sorting in them and I've tried to understand Zylum's 3d engine and its sorting. Unfortunately as far as I can tell it just sorts based on the average depth. Which is what mine attempts to do. My question is whether anyone knows a good yet fast sorting algortihm I could use, or if depth sorting just doesn't work for quadrilateral polygons and if it only works for triangles. ~Wolf_Destiny 
Author:  [Gandalf] [ Wed Nov 22, 2006 5:11 pm ] 
Post subject:  
Cervantes wrote: [Gandalf] wrote: Meh, I don't really have anything else to say, but it just surprised me that you would completely condemn such a... key ability in programming languages.
A key ability? What does this approach offer that functions (returning user defined types if necessary) do not? Convenience, maybe? Also, by "key" I meant something more along the lines of "common". Wolf_Destiny, as I recall zylum's 3D engine was quite good. Why don't you try asking him for a bit of help in understanding the sorting? 
Author:  BenLi [ Thu Jan 25, 2007 12:43 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
can somone expand upon this tutorial? I understand the ball thingie, but applying it into any sort of real situation would be harder. Zylum, why don't you explain your entry for the "20 lines" contest? 
Author:  CodeMonkey2000 [ Wed Jul 18, 2007 6:01 pm ]  
Post subject:  RE:[Tutorial] 3D graphics  
I don't get it. Why does the x and y values change as you move along the z axis? Why does the z value affect the position of the ball? It should only affect the size (in my mind anyway).
Is this considered 3D? 
Author:  HellblazerX [ Thu Jul 19, 2007 10:35 am ] 
Post subject:  RE:[Tutorial] 3D graphics 
CodeMonkey, you're right in that the zvalue doesn't affect the position of the ball. What it does affect is the size of the ball, as well as the size of the space between the zaxis and the ball. As the ball gets smaller, so does that space, and the ball appears to be moving closer to the zaxis, when in reality it isn't. 
Author:  CodeMonkey2000 [ Thu Jul 19, 2007 2:47 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
Why does the space between the zaxis and the ball also appear to be getting bigger/smaller? 
Author:  zylum [ Thu Jul 19, 2007 3:06 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
perspective 
Author:  Gooie [ Thu Jan 03, 2008 1:02 am ] 
Post subject:  Re: [Tutorial] 3D graphics 
Ok, so far this tutorial hasn't helped at all, actually it's really confusing. I think It needs a serious revamp. I'll try to write some of it, but anyone feel free to toss in any knowledge. I am just starting with 3D. So I only know a few of the subjects listed below. I've seen some 3D engines on CompSci, and I think that It would be great if some of those people could give up there secrets. So here are some areas needed to be covered. All of them together give the illusion of depth. relative size. Objects further away appear smaller. relative speed. Objects further away appear to move slower. zaxis blocking. Objects nearer appear in front of objects further away. haze. Objects further away are obscured by particles in the air. perspective. The apparent dimensions of an object taper as they get further away. Relative size and speed are also a result of perspective. light reflection/shading. The way light reflects from an object indicates its threedimensional shape, and its position in relation to the light source. I got this list from a website that explains 3D in great detail, for Shockwave. Translations could really help. http://www.jmckell.com/ 
Author:  andrew. [ Thu Jun 26, 2008 6:13 pm ]  
Post subject:  RE:[Tutorial] 3D graphics  
Don't know if I can do this, but I have created my own "3D thingy". It's basically a basketball and it drops to the ground. I read this, but it wasn't much help, so I just kind of made it up. Also, it may be my computer, but the end product of Windsurfer's tutorial doesn't do much. I think mine is much better, if I don't say so myself.
P.S. Some of my variable names don't make sense, but I couldn't think of anything better at the time. EDIT: Forgot to comment it. 
Author:  apomb [ Fri Jun 27, 2008 8:25 am ] 
Post subject:  RE:[Tutorial] 3D graphics 
Thats not exactly 3D, Andrew. there's no perspective, the ball is simply a 2D object. where is this third dimension? Moving a circle seemingly into the screen is hardly 3D visuals. Oh, and P.S. this is a TUTORIAL, not a submissions thread. just to point that out. 
Author:  SNIPERDUDE [ Sat Jun 28, 2008 1:29 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
Ok, I've MASTERED 2D graphics, and might as well start tampering around with 3D. I've noticed that in your tutorial WindSurfer that the Z coordinate always moves towards (0, 0). What if I wanted it (my (0, 0) coordinate) to move towards the center instead of lower left? So no matter where the X or Y coordinates are on the screen changing the Z will make it move closer to the middle... I'll experiment a bit and see if I can come up with anything. 
Author:  andrew. [ Sun Jun 29, 2008 9:38 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
Oh well, I tried. 
Author:  SNIPERDUDE [ Mon Jun 30, 2008 5:40 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
I've almost got it... still working on it though 
Author:  Lucas [ Thu Mar 24, 2011 8:14 pm ] 
Post subject:  RE:[Tutorial] 3D graphics 
setscreen ("graphics: 1200; 800") setscreen ("offscreenonly") var Cubes : int := 50 var x, y, z : array 1 .. Cubes of array 0 .. 8 of real var dx, dy : array 1 .. Cubes * 8 of int var clr : array 1 .. Cubes of int var Vx := 600 var Vy := 200 var Vz := 400 var l : int := 80 var dump : string (1) var mx, my, dump2 : int var dix, diz : int loop for a : 1 .. Cubes x (a) (0) := Rand.Int (350, 3750) y (a) (0) := Rand.Int (100, 1800) z (a) (0) := Rand.Int (3550, 3350) clr (a) := Rand.Int (1, 13) for b : 1 .. 8 if b = 1 or b = 2 or b = 5 or b = 6 then x (a) (b) := x (a) (0) + l else x (a) (b) := x (a) (0)  l end if if b = 1 or b = 4 or b = 5 or b = 8 then y (a) (b) := y (a) (0) + l else y (a) (b) := y (a) (0)  l end if if b < 5 then z (a) (b) := z (a) (0)  l else z (a) (b) := z (a) (0) + l end if end for end for loop exit when hasch mousewhere (mx, my, dump2) dix := (600  mx) div 50 diz := (400  my) div 50 for a : 1 .. Cubes for b : 1 .. 8 x (a) (b) := x (a) (b)  dix z (a) (b) := z (a) (b)  diz dx (((a  1) * 8) + b) := (((200 / (y (a) (b) + 200)) * (x (a) (b)  Vx)) + Vx) div 1 dy (((a  1) * 8) + b) := (((200 / (y (a) (b) + 200)) * (z (a) (b)  Vz)) + Vz) div 1 end for drawline (dx (((a  1) * 8) + 1), dy (((a  1) * 8) + 1), dx (((a  1) * 8) + 2), dy (((a  1) * 8) + 2), clr (a)) drawline (dx (((a  1) * 8) + 2), dy (((a  1) * 8) + 2), dx (((a  1) * 8) + 3), dy (((a  1) * 8) + 3), clr (a)) drawline (dx (((a  1) * 8) + 3), dy (((a  1) * 8) + 3), dx (((a  1) * 8) + 4), dy (((a  1) * 8) + 4), clr (a)) drawline (dx (((a  1) * 8) + 4), dy (((a  1) * 8) + 4), dx (((a  1) * 8) + 1), dy (((a  1) * 8) + 1), clr (a)) drawline (dx (((a  1) * 8) + 5), dy (((a  1) * 8) + 5), dx (((a  1) * 8) + 6), dy (((a  1) * 8) + 6), clr (a)) drawline (dx (((a  1) * 8) + 6), dy (((a  1) * 8) + 6), dx (((a  1) * 8) + 7), dy (((a  1) * 8) + 7), clr (a)) drawline (dx (((a  1) * 8) + 7), dy (((a  1) * 8) + 7), dx (((a  1) * 8) + 8), dy (((a  1) * 8) + 8), clr (a)) drawline (dx (((a  1) * 8) + 8), dy (((a  1) * 8) + 8), dx (((a  1) * 8) + 5), dy (((a  1) * 8) + 5), clr (a)) drawline (dx (((a  1) * 8) + 1), dy (((a  1) * 8) + 1), dx (((a  1) * 8) + 5), dy (((a  1) * 8) + 5), clr (a)) drawline (dx (((a  1) * 8) + 2), dy (((a  1) * 8) + 2), dx (((a  1) * 8) + 6), dy (((a  1) * 8) + 6), clr (a)) drawline (dx (((a  1) * 8) + 3), dy (((a  1) * 8) + 3), dx (((a  1) * 8) + 7), dy (((a  1) * 8) + 7), clr (a)) drawline (dx (((a  1) * 8) + 4), dy (((a  1) * 8) + 4), dx (((a  1) * 8) + 8), dy (((a  1) * 8) + 8), clr (a)) end for View.Update delay (0) cls end loop getch (dump) end loop I think that that is a good example that combines depth/perspective 
Author:  SNIPERDUDE [ Thu Mar 24, 2011 8:30 pm ]  
Post subject:  Re: [Tutorial] 3D graphics  
code tags in the future please, it makes it easier to read. Especially languagespecific.

: 