{{FULL_COURSE}} Homework 1 - Linear Algebra Library
Overview
-----
You will create a library of 3D linear algebra classes for applications in graphics while reinforcing your knowledge of object-oriented programming in C++. You will also write tests in the main function of your program in order to ensure your code behaves as expected.
Supplied Code
---------
Click here to access the homework's Github repository.
We will provide you with `vec4.h`, `mat4.h`, and `main.cpp` in the repository. You will have to create `vec4.cpp` and `mat4.cpp` files to complete the assignment. Do not make any modifications to the header (.h) files, since we will be testing your submissions with the headers we supplied you. Do not include any Qt data types (e.g. QVector) in this project.
To create a new Qt project in which to work, open Qt Creator and choose `Non-Qt Project` from the New Project dialog, then choose `Plain C++ Project`. Download the source files we provided into the Sources directory that Qt creates, then add them to the project. Overwrite the `main.cpp` file Qt created with our version.
Conceptual Questions (10 points, Due Friday, January 26 at 11:59 PM)
-------------
Before you begin the programming portion of this homework assignment, read and answer the following conceptual questions. Your answers should be submitted as a plaintext (`.txt`) file in your homework repository. When you
push your `.txt` file to your repository, your commit comment should be "CONCEPT ANSWERS".
* (5 pts) In `mat4.h`, there are several declarations of the `operator*` function. One declaration is `vec4 operator*(const vec4 &v) const` (line 89), while another is `vec4 operator*(const vec4 &v, const mat4 &m)` (line 106). Explain the mathematical difference in the output of these functions. Additionally, explain what each of the `const`s
does in each function.
* (5 pts) In `vec4.h`, there are two declarations of the `operator[]` function. Describe a situation in which __only__ the first function (line 25) can be used, and describe a situation in which __only__ the second function (line 28) can be used.
Help Log (5 points)
-------
Maintain a log of all help you receive and resources you use. Make sure the date and time, the names of everyone you work with or get help from, and every URL you use, except as noted in the collaboration policy. Also briefly log your question, bug or the topic you were looking up/discussing. Ideally, you should also the answer to your question or solution to your bug. This will help you learn and provide a useful reference for future assignments and exams. This also helps us know if there is a topic that people are finding difficult.
If you did not use external resources or otherwise receive help, please submit a help log that states you did not receive external help.
You may submit your help log as an ASCII (plain) text file or as a PDF. Refer to the Policies section of the course web site for more specifications.
Code Requirements (85 points, Due Tuesday, January 30 at 11:59 PM)
-------
### `vec4` Class (23 points) ###
Implement a four-dimensional vector class to be used in 3D graphics transformations. The orientation of the vector is context-dependent, but it is better to generally think of it as a column vector.
* Implement the three constructors in the header. Make sure you use initialization lists when appropriate. The default constructor should set all four elements of `data` to 0. (3 points)
* Override the [] operation for use in getting and setting elements (with 0 being the first element). Throw a `std::out_of_range` exception if the input index is out of bounds. Note that if you were writing this library for use in another program, you would not bother to perform bounds checking as this is a performance cost. (2 points)
* Override the assignment operator = (1 point)
Override Boolean operators (==, !=) for equality testing. The `float` elements of the `vec4`s should be exactly equal; do not use some small epsilon tolerance for equality. (2 points)
* Override the math operators (+, -, \*, /) and their corresponding assignment operators (+=, -=, \*=, /=) to support vector arithmetic (10 points)
* Implement the dot product and cross product functions (3 points)
* Implement a method length() which gets the geometric length of the input vector when measured across all four elements. (1 point)
* Implement the normalize() method, which adjusts the elements of the input vec4 so that its length becomes 1 when measured across all four elements. In other words, treat it as a generic vector with 4 elements, rather than a homogeneous 3D vector. You do __not__ need to handle zero-vectors as a special case. (1 point)
* Override the << operation for a print method that outputs the vector in a nice form. If you want to print floating point numbers to a fixed decimal place, look up how to use `std::fixed` and `std::setprecision` with `std::cout`. (1 point)
### `mat4` Class (47 points) ###
Implement a 4x4 matrix (a matrix with four columns, each one a `vec4`).
* Implement the four constructors in the header. The default constructor should create an identity matrix. (4 points)
* Implement the [] operator for use in getting and setting columns (with 0 being the first column). Throw a `std::out_of_range` exception if the input index is out of bounds. (2 points)
* Implement a `row(mat4 m, unsigned int i)` method which will return the 'i'th row in the input matrix (with 0 being the first row). Throw a `std::out_of_range` exception if the input index is out of bounds. (2 points)
* Implement the method `transpose(mat4 m)` which returns a new matrix in which each column is a row of the input matrix. (3 points)
* Implement the static function `rotate(float angle, float x, float y, float z)`, which returns a 3D rotation matrix about any arbitrary axis. `x`, `y`, and `z` are used to determine the axis around which the matrix will rotate. The input angle is in degrees, but remember that the sine and cosine functions expect radians for their input. You do __not__ need to sanitize the input of this function. (6 points)
* Implement the static function `translate(float x, float y, float z)`, which returns a 3D translation matrix. (4 points)
* Implemement the static function `scale(float x, float y, float z)`, which returns a 3D scale matrix. (4 points)
* Implement the static function `identity()`, which returns a 4x4 identity matrix. (2 points)
* Override the assignment operator = (1 point)
* Implement Boolean operators (==, !=) for equality testing. The `vec4` components of the `mat4`s should be exactly equal. (2 points)
* Implement the standard math operators (+, -, \*, /) and their corresponding assignment operators (+=, -=, \*=, /=) to support matrix arithmetic. (22 points)
* Implement the << operation for a print method that outputs the matrix in a nice form. (1 point)
You may add any additional methods, variables, classes, files, etc. that you deem necessary to complete the assignment, but for your own sanity you'll want to keep it as simple and clean as possible. You may use any standard C++ libraries (math.h, cmath, casset, iostream, etc) but do not download or use outside code for this assignment.
### Testing (15 points) ###
In `main.cpp`'s main function, write code that tests your implementation of the following functions in the `vec4` class.
* All three constructors
* operator<<
* operator=
* operator==
* operator!=
* dot product
* cross product
* normalize
Additionally, test your implementation of the following functions in the `mat4` class:
* All four constructors
* operator<<
* operator=
* operator==
* operator!=
* Rotate, with at least two different angles tested.
* Matrix-matrix multiplication
* Matrix-vector multiplication
* Vector-matrix multiplication
The output of your tests should contain the values you expected along with the values that were computed. We've provided one example test in `main.cpp` if you'd like a template to follow. If you want to check your matrix and vector math, the Moore lab computers have Matlab, and there are several online resources you can use such as [this online matrix math calculator](https://matrix.reshish.com/multiplication.php).
Coding Style (10 points)
------
To help you write better C++ code, we will score each of your homework assignments on three different style elements, which will change from week to week.
For this assignment, make sure you:
- Use loops to repeat operations where it would be useful to do so
- Re-use functions you wrote elsewhere to implement larger functions
- Use initializer lists in all of your constructors
Submission
--------
Commit and push your code via Git to your Github repository, then submit your code and a link to your repository on Canvas. *Make sure your code does not rely on the .h files being modified, as we will test your code with our own versions of these files*. Make sure you also commit your help log as a .txt file (refer the the Policies section of the web site for more information).