Notes on Perspective Projections

Previous    Next


VIEWING SPECIFICATION FOR PERSPECTIVE PROJECTIONS

The viewing specification for perspective projections takes the form:

set_projection_type(PERSPECTIVE) set_center_of_projection(copx,copy,copz)

set_view_plane_normal(vpnx,vpny,vpnz) set_view_reference_point(vrpx,vrpy,vrpz) set_view_up_vector(vupx,vupy,vupz) set_view_plane_window(umin,vmin,umax,vmax) set_front_back_clipping_planes(F,B)

set_viewport(sfmin,tfmin,sfmax,tfmax)

The first two determine the viewer's location. The second five determine the projection plane and the 3D clipping window (view volume). The last determines what fraction of the screen the final picture is displayed on.

Note that the COP, VPN, VRP and VUP are specified in world coordinates (x,y,z); the view plane window and front/back clipping planes are specified in view reference coordinates (u,v,n).

This is all a user has to do. He/she then can proceed to draw pictures using move_3d(x,y,z) connect_3d(x,y,z) text_3d(string) end_frame_3d()

Additionaly an init_graphics_3d() and an end_graphics_3d() may be useful to get things started and terminated.

Center of Projection:

The center of projection is the point COP. The projection is defined by drawing lines through COP that pass through the objects of interest and which create a projection on a view plane wherever they intersect that plane. The objects may be on either side of the plane, but they may not be behind the COP, relative to the projection plane.

View plane:

The view plane is determined by its normal direction - the view plane normal (VPN) - and any point in the plane - the view reference point (VRP). Clearly the plane must not contain the center of projection COP or no projection is possible.

View Plane Window:

The view plane window is a rectangular window on the view plane. The image will be projected onto the view plane window and the view plane window is then mapped to the viewport on the screen using the 2D package.

To specify the window we need to specify the "horizontal" and "vertical" directions (called u and v) on the view plane, and then the size of the window.

We specify the v direction to be the projection of a VUP vector onto the projection plane - it is easier for a user to give an idea of an up direction using a 3D VUP vector than to be forced to specify a 2D up vector that lies in an arbitrarily oriented plane. The u direction on the plane is defined as perpendicular to the v and n directions (n direction = VPN) and so that u,v,n is a right-handed system.

We define u,v,n coordinates by specifying their origin to be the VRP and their directions of increase to be the u,v,n directions.

We specify the window size by giving the u,v coordinates of the window corners: umin,vmin,umax,vmax.

View Volume:

We specify the view volume in two steps: 1. The infinite view volume is the semi-infinite pyramid which has the COP as its vertex and which intersects the view plane in the view plane window. It is semi-infinite because it does not go behind the COP. 2. The finite view volume is the section of the semi-infinite pyramid obtained by intersecting it with two planes, the front and back clipping planes, which are parallel to the view plane and at distances F and B from the view plane (measured along the VPN). If either plane is behind the view plane its corresponding distance is negative.

The PRP and the Book.

The book does not have a set_center_of_projection. Instead, it introduces a new concept - the PRP or projection reference point. The COP is then defined to be the PRP in the case of a perspective projection. The PRP is set using: set_projection_reference_point(prpu,prpv,prpn) and its coordinates are specified in u,v,n coordinates, not in world coordinates. So this last point is the only difference between my approach and the book.

Which method one uses is irrelevant - the two specifications are exactly equivalent. However it does make a difference to the user. Some things are easier if you specify COP directly in world coordinates, while other things are easier if you specify the COP relative to the window coords. I prefer my approach for understanding and ease of implementation. Conceptually a center of projection is the essence of a perspective projection - and I view it as ridiculous that the COP is only defined indirectly after a view plane coordinate system has been created.

VIEWING TRANSFORMATION FOR PERSPECTIVE PROJECTIONS

The viewing transformation for a perspective projection takes the cutoff pyramid viewing volume, which is oriented along the direction from the COP to the center of the window, into a canonical view pyramid which we will agree to have the form (this does not matter: we just need to choose something fixed): Length: parallel to z axis, and of length 1 Apex: at the origin. Back Plane: a 2 by 2 square centered on the z-axis at z=-1. (i.e. center of back plane (CBP) is the point (0,0,-1))

It follows that the four sides of the pyramid are at angles of 45 to the z axis. The front plane will end up at an arbitrary point between 0 and -1 - let us say at Z=zmin, a quantity we need to compute as part of the transformation. We cannot for example force the front plane to be at say z=-.5. Forcing the Apex to be at (0,0,0) and the back plane to be at z=-1 leaves us no further control.

We will now determine the transformation required to effect this. The steps involved are:

1. Translate the VRP to the origin Rotate so that the VPN becomes the +z direction and the VUP direction is in the +y part of the yz plane (which means that v axis is the y axis) Since rotations/translations dont affect angles, the view volume still has the same warped shape, although its end face is now perpendicular to z axis.

2. Next we translate the COP to the origin so that the apex of the pyramid is at the origin.

3. Next we shear the volume in both x and y so as to force it into a a pyramid centered along the z-axis. This will require a shearing transformation SHper(shx,shy) where shx, shy are chosen so that the shearing "pulls down" the pyramid to lie along the z axis. The shearing is determined by the COP since the problem is that the pyramid is oriented along the line from the COP to the center of window CW, which is not along the z axis (no shearing is needed if the that line is parallel to the VPN).

4. Finally we must scale the pyramid box so that the CBP lies at z=-1 and so that the sides are sloping at 45 degrees to z axis.

I cannot draw all these steps. See especially section 6.5.2 in the book.

NOTATION AND EQUATIONS FOR 3D PERSPECTIVE PROJECTIONS

The lack of ideal notation in the book causes some difficulty. I thought the following comments might be helpful.

The steps to generate Nper, the viewing transformation matrix for the perspective case, are: Sper SHper Tcop Ry Rx Rz Tvrp or: Sper SHper Tcop R Tvrp for short (R = RyRxRz).

Here Tcop moves the Center of Projection (COP) to the origin while Tvrp moves the View Reference Point (VRP) to the origin.

CRITICAL POINT:

Any quantity must be transformed to the coord. system in place at the time it is USED.

I will use the same notation I introduced for the parallel case Npar using primes carefully. The meaning of the primes is slightly different since the sequence of transformations is different. Much material is duplicated however so that this discussion can be fully self contained.

NOTATION:

We can create a consistent notation for this (not done in the book) by being very precise about the primes we add to points or vectors. Here are two possibilities:

Coordinate Name Stage Coords Notn 1 Notn 2

World Coords Start x,y,z P P View Reference Coords After R*Tvrp u,v,n P' P~ No Name After Tcop P'' P' No Name After SHper P''' P^ Normalized Projection Coords After Sper p,q,r P'''' P`

I will choose the first notation - ie multiple primes. Names for some coordinate systems are not even assigned as we dont use them much. Similarly names for the coordinates in a system (e.g. u,v,n) are also not assigned in some cases. The book is often sloppy here, using x,y,z to denote the three coordinates of a point in any of the systems. A nicer solution, which I use below, is to use either the correct symbol (x,y,z or u,v,n for example) if there is one, or to use the numbers 1,2,3 which will never lead to confusion.

So I will use: P = (Px,Py,Pz) = (P1,P2,P3) P' = (P'u,P'v,P'n) = (P'1,P'2,P'3) P'' = (P''1,P''2,P''3) whereas the book resorts to at times: P' = (P'x,P'y,P'z) which is nonsense since P' is in u,v,n coords and so has u,v,n coords, not x,y,z.

I will always omit the fourth coordinate of all points below, just remember that you need to include it, with value 1 in each case. For vectors, the fourth coordinate will be 0 as discussed below.

POINTS AND VECTORS:

A point is a location in space: P = (px,py,pz). A vector is a direction in space: V = (vx,vy,xz).

Given a PAIR of points P,Q the line from P to Q determines a vector V which is the direction from P to Q: V = Q-P.

Given a vector V, V determines an infinite number of pairs of points P, Q. Just take any point P, go any distance in the direction V from P, and call the result Q.

Sometimes we (book or me) are sloppy and call a point P a vector. In such cases what is usually meant is the direction from the origin to P, ie the vector VP = P-0. VP does have the same coordinates as P clearly and sometimes the notation P is used interchangeably for both P and VP.

In homogeneous coordinates, all points have a 4th coord. Usually the 4th coord is 1. Notice that V = Q - P = (qx,qy,qz,1) - (pz,py,pz,1) = (qx-px, qy-py, qz-pz, 0) so the vector has 4th coord zero. Vectors (directions) in a sense represent points at infinity - the point at the "end" of an infinite line in that direction. This is discussed briefly in section 6.1, paragraph 3.

Translations do not affect vectors. This is clear since a vector is a direction and will still point the same way if moved. If a vector is represented by two points P,Q as above, then P and Q both change (by the same amount) under a translation, but V = Q-P is left unchanged because the two additions just cancel.

In homogeneous coords this shows up as follows. If you have a vector V = (vx,vy,vz,0) and you multiply by a translation matrix T(DX,DY,DZ) you will find that the result is still (vx,vy,vz,0) independent of DX,XY,DZ.

So in the following when you apply transformations to a vector (such as VUP) you can apply only the rotations, scalings, shears to it, or you can safely include the translations as well - as long as you are using homogeneous coordinates. If you were using ordinary 3x3 matrices throughout, then applying a translation to a vector would change it, leading to much confusion.

COMMENTS ON TRANSFORMATIONS

1) The R*Tvrp part is determined by the following quantities given in world coordinates at the start: VRP, VPN, VUP Each of these quantities is defined in world coordinates so it is correct to write them with no primes. For example if the user calls set_view_ref_point(vrpx,vrpy,vrpz) then VRP = (vrpx,vrpy,vrpz). Assignment 5 computes R, Tvrp and R*Tvrp given these quantities.

2) The view volume is specified by the user by giving the window coords, front and back clipping plane in View Reference Coords u,v,n. Notice that this also defines other important points in the u,v,n system. Since it is the u,v,n system these points should all be denoted with a prime.

By definition the VRP is the origin for uvn, and so VRP' = (0,0,0). By definition the window has corners (umin,vmin), (umax,vmax) and the Center of Window CW is therefore at CW' = ((umin+umax)/2, (vmin+vmax)/2), 0).

Furthermore the whole viewing plane has n=0, the front clipping plane is at n = F and the back plane is at n = B (with B<0 if it is behind the plane). This is because the front and back clipping planes are defined to be parallel to the view plane.

To locate the Center Front Clipping Plane (CFP), we need to move along the center line CL until the 3rd coord is equal to F. We will compute the CL, CFP etc. in the prime system, right after the rotation.

For a perspective projection, the CL' is in the direction from the COP' to CW': CL' = CW' - COP' Note that this is not in general the direction perpendicular to the window.

Since the CL' passes through the center of window CW', a general point on the line has the form: P' = CW' + t*CL' where the parameter t ranges from -infinity to +infinity. If P' is on the front plane then P' will of course be the CFP' and its 3 coord. will be P'3 = F. So the value of t there will be given by: F = CW'3 + t*CL'3 or t = (F-CW'3)/CL'3

Then we get the CFP' by substituting into P' above: CFP'1 = CW'1 + t*CL'1 CFP'2 = CW'2 + t*CL'2 CFP'3 = CW'3 + F

In fact we know that CW' is ((umax+umin)/2, (vmax-vmin)/2),0) so that CW'3 = 0 above.

For the CBP we just replace F by B throughout (and recompute t of course).

Also useful later on (in the perspective case) is the lower left and upper right window corners which we might call LLW and URW. These are clearly given as: LLW' = (umin,vmin,0) URW' = (umax,vmax,0)

Basically all of these may be considered input data the user specifies - since he directly specifies umin,..,vmax and F,B.

Note: for some reason you may want to know where one of these items resides in world coords - perhaps the user wants the location of CFP printed in world coords. The solution is to remember that RT gets you from world to uvn coords, and thus: CFP' = R*Tvrp*CFP or CFP = (R*Tvrp)**-1 * CFP'

So we can always work backwards to world coordinates if needed.

3) The Center of Projection (COP) can be specified in one of two ways. In class I proposed defining set_cop(copx,copy,copz) or the like which gives the COP in world coordinates. Thus: COP = (copx,copy,copz)

In the book they suggest specifying a Projection Reference Point (PRP), specified in View Reference Coords u,v,n: set_prp(prpu,prpv,prpn), so that PRP' = (prpu,prpv,prpn) and then defining the COP as the PRP. Thus COP' = PRP'

I dont care which approach you use. HOWEVER it is essential to keep track of the primes here so you know which system a point is defined in. If you use my set_cop() approach then you can of course convert the specified COP to one in the uvn system using COP' = R*Tvrp*COP, or vice versa.

The transform Tcop that translates the COP to the origin is T(-COP'). It must use COP' rather than COP since the current coords after rotation are the prime coords.

4) In order to compute the shearing matrix SHper, it is necessary to convert all quantities to the '' coordinates that prevail after both the initial rotation RTvrp and the subsequent COP translation Tcop. This is because shearing is the next step and so any quantity such as CW to be used in computing a shearing matrix must be in that latest coord system. In other words we need to use CW'' in computing SHper.

The shearing step is required in order to force the center line of the view volume to lie along the 3rd axis, so that the view volume becomes symmetrical about that axis. The center line of the view volume - the line joining the COP and the window center CW - is in the direction CL'' = CW'' - COP'', which is just CW'' since COP'' is the origin.

The shearing matrix is then SHper(shxper,shyper) as in equation 6.30 in the book:

SHper(shxper,shyper) = 1 0 shxper 0 0 1 shyper 0 0 0 1 0 0 0 0 1

The shearing constants are computed so that SHper applied to CL'' shears it to the z-axis. Thus the requirement is that: SHper*(CL''1,CL''2,CL''3,1) = (0,0,CL''3,1) which on multiplying out requires that: shxper = -CL''1/CL''3, shyper = -CL''2/CL''3 which fully determines the shearing matrix. Note: we keep the annoying "per" in SHper and shxper etc. because we will need a similar SHpar for parallel projections, but with different constants.

5) The final step is the scaling to create a pyramid of length 1 in 3rd direction and base 2x2 in the other two directions, with the base being the back clipping plane, and the apex at the COP. We denote this scaling by Sper. The scaling is done in two steps S1per and S2per: first we scale the 1st and 2nd dimensions relative to 3rd, in order to create a pyramid with 45 degree faces; then we scale equally in all three dimensions to reduce the pyramid length to 1.

We can approach this in two ways:

a) brute force.

Here we use the transformations applied to various pyramid points to deduce their latest location and hence the size.

We can look at the upper right corner of the window, URW, which in the latest coordinates would be URW''': URW''' = SHper*Tcop*URW' and URW' was presented above. In order for the sloping faces to be at 45 degrees we will need to have URW1 = URW3 and URW2 = URW3 after scaling. Clearly this requires a scaling of: S1per = S(|URW'''3/URW'''1|, |URW'''3/URW'''2|, 1) where the absolute values are used to protect against negative scalings.

The length of the pyramid in the third dimension is the distance from the COP to the Center of Back clipping Plane (CBP) along the length of the box i.e. the third dimension. However we want to use the latest values for these, so that L3''' = third component of (COP''' - CBP'''). = - CBP'''3 since COP''' is the origin. CBP''' is not known, but CBP' is, so we would connect these: = - third component of SHper*CBP'' = - third component of SHper*Tcop*CBP' and of course we have formulae above for CBP'.

Thus the second scaling is: S2per = S(-1/L3''',-1/L3''',-1/L3''').

We can combine the two scalings into: Sper = S2per*S1per = S(URW'''3/URW'''1/L3''', URW'''3/URW'''2/L3''', 1/L3'''). which is exactly equation 6.39 of the text.

b) common sense.

Here we note that neither translations, rotations nor shearing change the lengths of vertical or horizontal lines in the pyramid. Consider the window which started with edges of size (umax-umin) and (vmax-vmin). Since it ends up centered about the 3 axis, the window upper right corner must be at ((umax-umin)/2, (vmax-vmin)/2), w). Its third component w must be the same as that of any other point in its plane, for example the VRP: so that w = VRP'''3 = third component of SHper*Tcop*VRP' = third component of Tcop*VRP' = VRP'3 - COP'3 = -COP'3 since the SHper does not affect coordinates in the 3rd direction, and VRP' is the origin.

Knowing the coordinates of the window upper right corner, we proceed as before. The first scaling is therefore: S1per = S(-2VRP'''3/(umax-umin), -2VRP'''3/(vmax-vmin), 1)

The back clipping plane was originally distance B from the view plane and this will still be true after translation/shearing. So the third component of the back clipping plane must be VRP'''3 + B. Therefore the final scaling, equal in all 3 directions, should be S2per = S(1/(VRP'''3 + B),1/(VRP'''3 + B),1/(VRP'''3 + B))

Combining these two scaling leads to Sper = S2per*S1per which is exactly equation 6.39 of the text.

I presented the two approaches as it is nice to see that we can really allow the brute force method (very easy on a computer which can compute transformation applications fast, but cannot think in common sense) to guide us through the whole operation if we wish.

6) Clipping and Projection

Having transformed our view into the canonical view volume, the operation of projection is now simpler. We need to determine the location of the view plane however, which we will call zview. Since the VRP is in the view plane, clearly zview is just the z component of the final VRP: zview = VRP''''3 = Third component of Sper*VRP''' = - VRP'''3 / (VRP'''3 + B) where we have used the third scaling factor from Sper explicitly.

So our view situation is now of the form:

*| * | * | * | zmin *|zview |z=-1 | | | z=0 * | | | * | | | *| | | * | | * | * | * | * |

Now suppose we wish to project a point Q in world coordinates. The projection operation is to draw a line from the COP (0,0,0) through the desired transformed point Q'''' and find the point Q''''' where the line intersects the plane z=zview: . The equation of the line is obviously: P = tQ'''' where 0 <= t < infinity

This intersects z=zview at the point t given by: P3 = zview, or tQ''''3 = zview, i.e. t = zview/Q''''3

The projection coordinates - qx and qy say - are then given by: qx = Q'''''1 = tQ''''1 = zview*Q''''1/Q''''3 qy = Q'''''2 = tQ''''2 = zview*Q''''2/Q''''3. We would then handle the 2D coordinates (qx,qy) using the 2D package.

This operation may be represented if desired as multiplication by a matrix Mper:

Mper = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1/zview 0

although in practice it is cheaper to simply compute x, y explicitly. If Mper is used, we must divide out by the 4th coordinate to get the correct 2D qx and qy. It is trivial to check that Mper*Q'''' has the coordinates stated in the 1 and 2 directions..

Before projection however we should perform clipping against the 6 faces of the canonical view volume.

7) The 2D graphics window.

As we project clipped lines in (7) we will draw them by making calls to 2D line drawing routines. We can utilize our 2D graphics package for drawing these provided we set its window correctly. The correct window is the transformed original window. So we define: (pmin,qmin,rmin) = LLW'''' = Sper*SHper*Tcop*LLW'

(pmax,qmax,rmax) = URW'''' = Sper*SHper*Tcop*URW'

and then call set_window_2d(pmin,qmin,pmax,qmax) - or whatever order was used in 2d (it might have been set_window_2d(pmin,pmax.qmin,qmax)).

Here again we can also use common sense. The transformed window clearly is at LLW'''' = (-1,-1,?), URW'''' = (1,1,?). Thus we want: set_window_2d(-1,-1,1,1) ( or maybe set_window_2d(-1,+1,-1,+1)).

(In the perspective case, the box is a pyramid of changing cross-section. So in that case the common sense approach does not give the answer whereas the brute force approach is still correct.)

8) 2D viewport.

The whole contents of the 2D window (and therefore the clipped 3D world) is to appear in the fraction of the physical screen represented by the viewport set in set_viewport_2d(Umin,Vmin,Umax,Vmax) where each Umin, .., Vmax must be between 0 and 1 (or maybe set_viewport_2d(Umin,Umax,Vmin,Vmax)).

Again the 2D graphics package will do this automatically for you once you call set_windows_2d and set_viewport_2d().

NOTE: The Umin etc. in this paragraph have nothing to do with the umin etc. we used above to specify the window on the 3D projection plane. I have used the names Umin etc. only because we called these umin etc. in the 2D viewport discussion. I used capital first letters to at least distinguish them. It might be better to call them screen fractions (sf) to avoid confusion so that one might call:

set_viewport_2d(sfxmin,sfymin,sfxmax,sfymax) or set_viewport_2d(sfxmin,sfxmax,sfymin,sfymax)


Previous   Next