Sunday, January 27, 2008

Quick and Dirty 3-D Rendering

By using a handy shortcut, you can render 3D objects painlessly.

Usually this is done using transformation matrices. This sort of matrix manipulation was actually discovered back in the 18th century, but like many great mathematical discoveries, had no real practical application. Until the modern era, that is, when someone discovered that this trick was perfect for rendering 3D graphics. It lets you rotate, scale, shear, etc. any image, and the really nice thing is that once you decide all the transformations you want, you can reduce them to a single matrix and so compute the positions of everything you want to draw rather quickly.

But unless you live and breathe the stuff, it’s too complicated to remember how to set it up off the top of your head, and a lot of code even if you know how. So here’s a tip that will get you rendering 3D objects in no time.

First, draw yourself a set of axises, like so:

It doesn’t have to be very accurate, just so as it looks fairly proportional. Now, imagine that each of the arrows is one unit long. You need to write functions that return x and y for a given (x,y,z) point. So ask yourself — for each unit of x, how much do we actually move horizontally? How about for each unit of y? For each unit of z, we don’t move horizontally at all, but for the other two, you can make a guess. Let’s say the tip of the x axis is 16 pixels to the right of the origin, and the tip of the y is 20. Again, accuracy isn’t important, as long as you’re in the ballpark and the numbers are proportional. Since you want it to appear in the center, add an offset that’s half the width of the screen. So your method for determining the screen x coordinate of your point will look something like this:

private int getX( Point p )
return CENTER_X + p.x*16 + p.y*20 + p.z*0;

Obviously, the p.z*0 could have been left out, but I leave it there for illustration.

Similarly, the screen y coordinate can be determined just by guessing the offset of the tips of the x, y, and z axises on our sketch. Looks like about -10, 5, and -20 respectively (remember y coordinates count down from the top in most computer graphics systems). So our function for determining the screen y of your point will look like this:

private int getY( Point p )
return CENTER_Y + p.x*-10 + p.y*5 + p.z*-20;

Let’s see it in action. Here’s an applet that defines a few lines in terms of their 3D endpoints, and then draws them on our 2D screen using the methods described above. Specifically, it defines all the lines necessary to draw the cube that stretches from -1 to 1 on each axis. Give it a click to run it:

Enable Java in your browser to see it.

(Java source for main class here. Parent applet here.)

Not bad, huh? It’s handy for quick visualizations, and you’ll probably see it again here before long.


Post a Comment

Subscribe to Post Comments [Atom]

<< Home