Rendering 3D objects in 2D

Hello,
I am making a terrain generator in VB, simply to learn how to render/draw 3d objects. I want to do it completely by hand(software render) so that i know how it works.(yes i realize how slow this will be) If anyone could give me a mathmatical formula to convert 3d points to a 2d plane, i would greatly appreciate it.

Instead of giving you just the equations, I will also show you how they are derived, since it is very simple.

Usually, you have a camera located at (0,0,0) looking down in the direction of the negative z axis.
When you are looking at your screen, the z axis points back (away from you), the x axis points left, and the y axis points up. (right handed coordinate system).

Suppose, from above, you look at a 3d point P that you want to project to your 2d screen. The ascii image that follows shows you how you would project
the x coordinate to the screen. (ignore the "-"s)
P(x,y,z).—x---.
------------------|
------------------|
------------------| --length: -z -d
------------------|
…+…x’…|… Screen
------------------|
------------------|
------------------| --length d
------------------|
------------------|
-------------------C (0,0,0)

C is the camera, and the “+” is where your dot should appear on the x axis of the screen.

What we are looking for here is just x’. Note that the length of the vertical line from the camera to the point is -z because a length is always positive and we are looking down in the direction of the negative z. Also the distance from the camera to the screen is d.

From that you can obtain easily x’ by calculating the ratios between the 2 similar triangles.

-z / x = d / x’
or
x’ = d*x / -z

Similarly you obtain y’
y’ = d*y / -z

So, the projection of a 3d point on a 2d plane is (dx/-z, dy/-z). (0,0) represents the center of your screen.

I have one suggestion for you. Do not hardcode the length from the camera to the screen d. Instead define a vision angle theta so that when you resize your screen you obtain the same perspective. You can get d with a little trigonometry with

d = (w/2) / tan(theta / 2)

Also note that keeping the camera at (0,0,0) simplifies things a lot. If you want to move the camera around (rotation or translation), keep your camera at (0,0,0) but store the transform you have applied so far to the camera (e.g. angle xaxis 20degrees, position (30,12,5)) and then for each point that you project, apply the inverse transform before projecting (e.g. translate by -30,-12,-5 and rotate -20degrees xaxis).

I am sorry, I assumed you meant projecting a 3d point to a 2d “screen”

If you want to project a 3d point p to an arbitrary plane Pl described by a 3d point o (origin), and 2 orthogonal unit vectors u and v (the axes of the plane), you can do the following steps to find the projection p’ of p on Pl:

  1. Find the normal vector of the plane n by doing a cross product u x v

n.x = u.yv.z - u.zv.y
n.y = u.z * v.x - u.x * v.z
n.z = u.x * v.y - u.y * v.x

n is perpendicular to the plane

  1. Trace a vector between any point on plane Pl, say the origin, and point p. call it w

w = p - o

  1. Get the length L of the projection of w on n
    Since n is normalized, you can obtain this simply by doing

L = dotProduct(w,n) = wxnx + wyny + wz*nz

This corresponds to the “distance” between p and the plane. This will be negative depending on what side of the plane p is (but is is ok).

  1. You can obtain p’ by doing :

p’ = p - L*n

p’.x = p.x - Ln.x
p’.y = p.y - L
n.y
p’.z = p.z - L*n.z

So, more precisely
n.x = u.yv.z - u.zv.y
n.y = u.z * v.x - u.x * v.z
n.z = u.x * v.y - u.y * v.x

L = (p.x - o.x)*n.x + (p.y - o.y)*n.y + (p.z - o.z)*n.z

p’.x = p.x - Ln.x
p’.y = p.y - L
n.y
p’.z = p.z - L*n.z

voila! p’ is on the plane.

There might be shorter ways of doing this
this is 12 multiplications

Also there are other types of projections, this one is the simplest