## Description

## Objective:

The objective of this project is to demonstrate understanding of, and competence using, graphical algorithms and techniques as discussed in lectures. Given the specifications of a camera system you should demonstrate that you know how to perform the

transformations of the 3-D pipeline by transforming world co-ordinates into normalised device coordinates. You will then open a simple viewport using OpenGL and display a polygon

that was placed in the world.

I will run your program on two scenarios (camera system specifications). The assignment

counts for 75% of your semester grade so it will be marked out of 75. For reference the

marking scheme is given below.

Category Query Marks

File submitted 5

Clean compilation 10

What is zv vector? 1 10

What is yv vector? 2 10

What are 8 corners of frustum in VC? 3 10

Given p1 in WC what is it in VC? 4 6

Given p2 in WC what is it in VC? 5 2

Given p3 in WC what is it in NDC? 6 6

Draw a given triangle in a given viewport 7 16

Total 75

Table 1: Marking scheme for assignment.

## Your job:

Following the transformation matrices given in the lectures implement a perspective mapping. You should put all of your code in a single file (tut, tut!) called camsys.cc.

As this is a 3-D camera system you will be working with 4-D vectors and matrices. You will

need to be able to compute dot product (a.k.a. inner product) and cross product of vectors,

normalize vectors, and multiply matrices of these sizes.

To do these matrix calculations you could either write your own or you could rely on the

very cool eigen library. (See here for initial details, especially the section “Compiling and

running your first program”.) As described there, when compiling your program I will add

1

in an include path to find the eigen files

g++ -I /path/to/eigen/ camsys.cc -o camsys

so you should follow the template provided there.

If you don’t want to use this don’t worry about the above.

Input Format: All input to your program will come from standard input, the keyboard.

The input will be given entirely as numbers, either as doubles for distances, triples of

doubles for points/vectors, or ints for window dimensions or for the query number. In

order to set up the camera system the input you will need will be

1. camera position;

2. camera aim point;

3. the up-vector, a hint as to where the camera’s y-axis should point;

4. two numbers that represent, respectively, the distance to the near and far planes of

the frustum from the apex of the pyramid;

5. the width and height of the clipping window on the near plane.

The camera system is now fully specified and at this point your program, camsys, should

read a single int that represents a query, respond to that query, and exit. One run of the

program, one query. Depending on the query given, you will need to read some more input

data. Table 2 below details the exact inputs you will need to read to respond to a given

query.

## Some description of each query:

1. There is no additional input required for this since it just works off the camera specs

previously given. Please give the vector as it appears in world coordinates since the

vector in VC is obviously (0, 0, 1)T

! The vector should be normalized (unit-length);

2. Same applies here;

3. Output the eight corners of the frustum in the order blf, tlf, trf, brf, blr, tlr, trr, brr,

where ’b’, ’t’, ’l’, ’r’, ’f’ and ’r’ stands for, respectively, bottom, top, left, right, front

and rear. That is, output the front (near) plane then the rear (back, far) plane in

counter-clockwise order starting with the bottom-left corner of each;

4. After reading the point as three doubles output its representation in VC;

5. ditto;

6. This time apply the additional transformations to find, for the point you read, its

representation in normalized device coordinates. Assume, as OpenGL does that the

NDC cube extends from (−1, −1, −1) to (+1, +1, +1);

2

7. In order to respond to this query you will need to read three points from stdin that

make up a triangular face of some object in the world and followed by two ints that

are the width and height of a viewport in pixels. Create an OpenGL window of those

dimensions and, draw the camera’s view of the face in this viewport.

Query Number Required Inputs

What is zv vector? 1 –

What is yv vector? 2 –

What are 8 corners of frustum in VC? 3 –

Given p1 in WC what is it in VC? 4 3 doubles

Given p2 in WC what is it in VC? 5 3 doubles

Given p3 in WC what is it in NDC? 6 3 doubles

Draw a given triangle in a given viewport 7 9 doubles, 2 ints

Table 2: Inputs required per query.

A typical input to your program would be:

(6.0,5.0,4.0)

(9.9,8.8,7.7)

(6.0,5.0,4.0)

2.0 6.0

6 8

7

(1.0,0.0,0.0)

(0.0,1.0,0.0)

(0.0,0.0,1.0)

400

300

That was for query 7. For query 4, assuming the same camera parameters, it would be

(6.0,5.0,4.0)

(9.9,8.8,7.7)

(6.0,5.0,4.0)

2.0 6.0

6 8

4

(9.9,8.8,7.7)

## Output Format:

Each point or vector should be output as a triple of numbers separated by commas with

enclosing parentheses. All numbers output should be in floating point format and should be

rounded to 6 decimal places. Output one “thing” per line, with no extraneous text. The

expected response to a query that asked for a vector or point would be:

3

(-1.234567,6.000000,1.543210)

Useful Resources: Please email me if there are parts you do not understand. Have a look

at the eigen library though this is not compulsory. You will have learnt a little Matlab

in first year. Octave, its open source equivalent or itself is very handy for verifying your

matrix calcs. For example to perform a cross product in octave and then to calculate the

normalized version of a vector this is how it would look.

octave:1> u=[1.1,2.2,3.3]

u =

1.1000 2.2000 3.3000

octave:2> v=[4.4,5.5,6.6]

v =

4.4000 5.5000 6.6000

octave:3> cross(u,v)

ans =

-3.6300 7.2600 -3.6300

octave:4> cross(v,u)

ans =

3.6300 -7.2600 3.6300

octave:5> U=u/norm(u)

U =

0.26726 0.53452 0.80178

Good luck.

4