I am currently working with using Bezier curves and surfaces to draw the famous Utah teapot. Using Bezier patches of 16 control points, I have been able to draw the teapot and display it using a 'world to camera' function which gives the ability to rotate the resulting teapot, and am currently using an orthographic projection.

The result is that I have a 'flat' teapot, which is expected as the purpose of an orthographic projection is to preserve parallel lines.

However, I would like to use a perspective projection to give the teapot depth. My question is, how does one take the 3D xyz vertex returned from the 'world to camera' function, and convert this into a 2D coordinate. I am wanting to use the projection plane at z=0, and allow the user to determine the focal length and image size using the arrow keys on the keyboard.

I am programming this in java and have all of the input event handler set up, and have also written a matrix class which handles basic matrix multiplication. I've been reading through wikipedia and other resources for a while, but I can't quite get a handle on how one performs this transformation.

## Best Solution

I see this question is a bit old, but I decided to give an answer anyway for those who find this question by searching.

The standard way to represent 2D/3D transformations nowadays is by using

homogeneous coordinates.[x,y,w]for 2D, and[x,y,z,w]for 3D. Since you have three axes in 3D as well as translation, that information fits perfectly in a 4x4 transformation matrix. I will use column-major matrix notation in this explanation. All matrices are 4x4 unless noted otherwise.The stages from 3D points and to a rasterized point, line or polygon looks like this:

isotropic; scaling and shearing makes the normals malformed.perspective divide.Sutherland-Hodgeman clippingis the most widespread clipping algorithm in use.This stage is the actual projection, because z isn't used as a component in the position any more.

## The algorithms:

## Calculation of field-of-view

This calculates the field-of view. Whether tan takes radians or degrees is irrelevant, but

anglemust match. Notice that the result reaches infinity asanglenears 180 degrees. This is a singularity, as it is impossible to have a focal point that wide. If you want numerical stability, keepangleless or equal to 179 degrees.Also notice that 1.0 / tan(45) = 1. Someone else here suggested to just divide by z. The result here is clear. You would get a 90 degree FOV and an aspect ratio of 1:1. Using homogeneous coordinates like this has several other advantages as well; we can for example perform clipping against the near and far planes without treating it as a special case.

## Calculation of the clip matrix

This is the layout of the clip matrix.

aspectRatiois Width/Height. So the FOV for the x component is scaled based on FOV for y. Far and near are coefficients which are the distances for the near and far clipping planes.## Screen Projection

After clipping, this is the final transformation to get our screen coordinates.

## Trivial example implementation in C++

If you still ponder about this, the OpenGL specification is a really nice reference for the maths involved. The DevMaster forums at http://www.devmaster.net/ have a lot of nice articles related to software rasterizers as well.