Programming Assignments


Overview

There will be four programming assignments in this course. But, these will be more than just exercises in writing code in C++. This will be an exercise in Software Engineering. You will learn about the Agile approach to Software Engineering, specifically that approach called Scrum. Details of Scrum will be discussed in class. On this page you will find the basics of what is required for each programming assignment.

You can follow each of the links below to see how programming assignments will be posted and how you should execute each one.

  • Statement of Work
    This shows the format in which you will receive a programming assignment posted on the web page. In many professional software engineering situations it is your customer who will provide you with a Statement of Work describing what, in the customer's opinion, states exactly what they want the software to do.

  • Scrum Report
    For each programming assignment you will be given a copy of a Scrum report. This is part of a project Backlog, the list of requirements as used in Scrum. The report lists the Epics which must be completed in each of two Sprints. Each Epic is broken down into a number of very specific User Stories (Requirements) each of which must be completed. There is a column in which you will enter the date on which you completed that user story. Details of the backlog, epics, and user stories will be discussed in class.

  • Sprint 1 Code
    This shows the C++ code created during Sprint 1 for this programming assignment.

  • Sprint 2 Code
    This shows the C++ code created during Sprint 2 for this programming assignment.

  • The subject matter of this project
    What do you do if you have not taken Linear Algebra and don't understand what this programming assignment is asking for?











This is a demonstration program to illustrate the format of programming assignments when posted and
the required documentation for all programming assignments.

THIS IS NOT YOUR FIRST PROGRAMMING ASSIGNMENT.



Programming Assignment 1

Posted: Tuesday, January 26
Sprint 1: January 26 - January 28
Sprint 2: January 28 - February 4
DDD: Thursday, February 11

Statement of Work
Programming Assignment 1

1.0 Overview
     There are many operations in Linear Algebra that are used in rendering scenes in 3D graphics applications. Many of these operations are a part of the
     OpenGL libraries. In this programming assignment you will create a utility class which implements many of these operations.

2.0 Requirements
     The student shall define, develop, document, prototype, test, and modify as required the software system.

     2.1 This software system shall define a linear algebra utility class called LinearAlgUtil (file names shall be LinearAlgUtil.h and LinearAlgUtil.cpp)
     which contains a number of utility functions for performing graphics rendering related linear algebra operations.

          2.1.1 The LinearAlgUtilclass shall contain private variables as described below:
                2.1.1.1 An instance of the structure Point2D (see section 2.1.3 below) called m_Pt. This structure shall be used as an intermediate data container
               for the point rotation functions.

           2.1.2 The LinearAlgUtil class shall contain public functions as described below:
                2.1.2.1 LinearAlgUtil(), ~LinearAlgUtil() A default constructor and destructor.

                2.1.2.2 int DotProduct(int u[], int v[]). This function takes as arguments 2 one-dimensional arrays, each containing 3 ints, representing two
                vectors u and v. The function calculates the Dot Product (u dot v) and returns the result as an int.

                2.1.2.3 void CrossProduct(int u[], int v[], int Result[]). This function takes as arguments 3 one-dimensional arrays, each containing 3 ints. The
                first two array arguments represent two vectors u and v. The function calculates the Cross Product (u x v) and places the resulting vector in the
                third array argument.

                2.1.2.4 void MatrixMultiply4X4(int M1[][4], int M2[][4], int Result[][4]). This function takes as arguments 3 two-dimensional arrays, each
                containing 4 rows and 4 columns ints. The first two array arguments represent two matrices which are to be multiplied together and the resulting
                matrix is placed in the third array argument.

                2.1.2.5 void RotatePoint2D_Ptr(Point2D *pt, double angle). This function takes as arguments a pointer to a Point2D structure and a double
                giving the angle in degrees through which to rotate the given point. Upon return the x and y fields of the Point2D structure will hold the rotated
                point coordinates.

                2.1.2.6 void RotatePoint2D_Ref(Point2D& pt, double angle). This function takes as arguments a reference to a Point2D structure and a
                double giving the angle in degrees through which to rotate the given point. Upon return the x and y fields of the Point2D structure will hold the
                rotated point coordinates.

           2.1.3 A structure called Point2D shall be defined in the LinearAlgUtil.h. It shall contain 2 fields, a double called x and a double called y. It will be
           used to represent a point in 2D space.

     2.2 The class file and its' associated header file must be capable of being compiled and linked in with the instructor's driver program (which will
     main) for testing. Do not turn in your source file containing contain main. It will not be used for testing.

3.0 Deliverables
     These products shall be delivered electronically via e-mail as specified below to the instructor.

     3.1 Scrum Report -- The student shall provide a Scrum Activity Report for instructor
     approval NLT (Not Later Than) Thursday, February 13.

     3.2 Program source files -- The student shall provide fully tested electronic copies of the .cpp and .h files. These files must be submitted to the
     instructor via e-mail. The files shall be delivered NLT Thursday, February 13.

4.0 Period of Performance
     The period of performance of this assignment is 21 days from the date of assignment. Only under special circumstances will any deliverables be
     accepted after the DDD date posted in the Course Syllabus.

A note on program grading: The instructor will test your program by compiling your LinearAlgUtil.cpp and LinearAlgUtil.h files with a driver program containing a main() function. This driver will exhaustively test your source code.








This is an example of the Scrum Report which you will fill out as you complete each programming assignment.
It is to be turned in with your source code.

THIS IS NOT THE SCRUM REPORT FOR YOUR FIRST PROGRAMMING ASSIGNMENT.


Programming Assignment 1 Scrum Report

Name      Justin A. Student     

Sprint 1
     Epic: As a student of CS 221 I need to create the basic program architecture.
Backlog of User Stories
Done Date*
Create the project in Visual Studio, add a source file and add a main function to the source file.
1/27/2016
Add .h and .cpp files for the LinearAlgUtil class.
1/27/2016
Write the class definition in LinearAlgUtil.h.
1/27/2016
Write stub function definitions in LinearAlgUtil.cpp for each function in the class. (Functions returning a value should return zero, NULL, etc. as appropriate.)
1/27/2016
Add a cout line to each function just to report that the function was reached. Do this for the constructors and destructor also.
1/27/2016
Add code to main to create and instance of LinearAlgUtil. Call all functions and verify that all were reached.
1/27/2016


Sprint 2
     Epic: As a student of CS 221 I need to plan how to test each function.
     Epic: As a student of CS 221 I need to implement and verify each function.
Backlog of User Stories
Done Date*
For each function in LinearAlgUtil determine exactly how you will test the function automatically from main and add code to perform each of the automatic tests.
1/30/2016
Add code, test and verify all functions.  
     LinearAlgUtil() - class constructor
1/30/2016
     ~LinearAlgUtil() - class destructor
1/30/2016
     DotProduct()
2/1/2016
     CrossProduct()
2/1/2016
     MatrixMultiply4X4()
2/2/2016
     RotatePoint2D_Ptr()
2/3/2016
     RotatePoint2D_Ref()
2/3/2016
           *Done means you have fully implemented the code AND fully tested it.






Sprint 1 Code

Below you will see the actual code created for this demonstration project during Sprint 1. This includes the file with main() showing the testing and the LinearAlgUtil.h and LinearAlgUtil.cpp files. There is also an image of the on-screen output after a run of the compiled program.

File: Prog1Main.cpp


//=============================================================================
// Programming Assignment Demonstration
// File: Prog1Main.cpp
// This program demonstrates the steps to be completed in Sprint 1.
//
// Author: Dr. Rick Coleman
// History: Project created December 2015
//=============================================================================

#include <iostream>
#include "LinearAlgUtil.h"

using namespace std;


void main()
{
	int vect1[3];		// Array of 3 ints to represent a vector in XYZ space
	int vect2[3];		// Array of 3 ints to represent a vector in XYZ space
	int vectResult[3];	// Array of 3 ints to represent a vector in XYZ space

	int matrix1[4][4];		// 2-D Array of ints to represent a matrix
	int matrix2[4][4];		// 2-D Array of ints to represent a matrix
	int matrixResult[4][4];	// 2-D Array of ints to represent a matrix

	Point2D pt;			// Structure for testing point rotate functions

	char ans;			// Input from user
	int testResult = 0; // Keep up with count of successful tests
	int expectedResult = 0;

	cout << "Running tests of LinearAlgUtil functions.\n\n";

	LinearAlgUtil *lau = new LinearAlgUtil();	// Create test instance
	// Test constructor by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil constructor.\"? (Press Y or N)";
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";

	// Test the DotProduct function
	lau->DotProduct(vect1, vect2); // Call DotProcuct function
	// Test function call by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil::DotProduct function.\"? (Press Y or N)";
	cin.ignore(10, '\n');	// Flush buffer before next input
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";

	// Test the CrossProduct function
	lau->CrossProduct(vect1, vect2, vectResult); // Call CrossProduct function
	// Test function call by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil::CrossProduct function.\"? (Press Y or N)";
	cin.ignore(10, '\n');	// Flush buffer before next input
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";

	// Test the MatrixMultiply4X4 function
	lau->MatrixMultiply4X4(matrix1, matrix2, matrixResult); // Call MatrixMultiply4X4 function
	// Test function call by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil::MatrixMultiply4X4 function.\"? (Press Y or N)";
	cin.ignore(10, '\n');	// Flush buffer before next input
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";

	// Test the RotatePoint2D_Ptr function
	lau->RotatePoint2D_Ptr(&pt, 0.0); // Call RotatePoint2D_Ptr function
	// Test function call by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil::RotatePoint2D_Ptr function.\"? (Press Y or N)";
	cin.ignore(10, '\n');	// Flush buffer before next input
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";

	// Test the RotatePoint2D_Ref function
	lau->RotatePoint2D_Ref(pt, 0.0); // Call RotatePoint2D_Ptr function
	// Test function call by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil::RotatePoint2D_Ref function.\"? (Press Y or N)";
	cin.ignore(10, '\n');	// Flush buffer before next input
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";

	// Test the destructor
	delete lau;
	// Test function call by Observation
	cout << "Did you see printed:\n\t\"Now executing LinearAlgUtil destructor.\"? (Press Y or N)";
	cin.ignore(10, '\n');	// Flush buffer before next input
	cin.get(ans);
	if((ans == 'Y') || (ans == 'y'))
		testResult++;
	expectedResult++;
	cout << "\n\n";


	// Output result of testing
	cout << "\nFinal result of testing = " << testResult << endl;
	cout << "Expected to get a count of " << expectedResult << endl << endl;
	}
			


File: LinearAlgUtil.h


//=======================================================================
// LinearAlgUtil.h
// Header file defining a class of Linear Algebra Utility functions.
//   This program is a demonstration for programming assignments in
//   CS 221 following the Agile approach of Scrum.
//
// Author: Dr. Rick Coleman
// History: Created December 2015
//=======================================================================
#pragma once;

// Define the point structure
struct Point2D
{
	double x;
	double y;
};

class LinearAlgUtil
{
	private:
		Point2D m_Pt;	// Temp Point2D struct for use by point rotate functions

	public:
		LinearAlgUtil();						// Default constructor
		~LinearAlgUtil();					// Destructor
		int DotProduct(int u[], int v[]);			// Calculate the Dot Product of vectors u and v
		void CrossProduct(int u[], int v[], int Result[]);	// Calculate the Cross Product of vectors u and v
		void MatrixMultiply4X4(int M1[][4], int M2[][4], int Result[][4]);// Calculate a 4x4 matrix multiplication
		void RotatePoint2D_Ptr(Point2D *pt, double angle);	// Rotate a point in 2D using pointer to Point2D struct
		void RotatePoint2D_Ref(Point2D& pt, double angle);  	// Rotate a point in 2D using reference to Point2D struct
};
			


File: LinearAlgUtil.CPP


//===========================================================================
// LinearAlgUtil.cpp
// Implementation file defining a class of Linear Algebra Utility functions.
//   This program is a demonstration for programming assignments in
//   CS 221 following the Agile approach of Scrum.
//
// This file demonstrates the implementation to be completed in Sprint 1.
//
// Author: Dr. Rick Coleman
// History: Created December 2015
//===========================================================================
#include "LinearAlgUtil.h"
#include <iostream>

using namespace std;

//------------------------------------------------
// Default constructor
//------------------------------------------------
LinearAlgUtil::LinearAlgUtil()
{
	cout << "Now executing LinearAlgUtil constructor.\n";
}

//------------------------------------------------
// Destructor
//------------------------------------------------
LinearAlgUtil::~LinearAlgUtil()
{
	cout << "Now executing LinearAlgUtil destructor.\n";
}

//-------------------------------------------------------
// Calculate the Dot Product of vectors u and v
//-------------------------------------------------------
int LinearAlgUtil::DotProduct(int u[], int v[])
{
	cout << "Now executing LinearAlgUtil::DotProduct function.\n";
	return 0;
}

//-------------------------------------------------------
// Calculate the Cross Product of vectors u and v
//-------------------------------------------------------
void LinearAlgUtil::CrossProduct(int u[], int v[], int Result[])
{
	cout << "Now executing LinearAlgUtil::CrossProduct function.\n";
}

//-------------------------------------------------------
// Calculate a 4x4 matrix multiplication
//-------------------------------------------------------
void LinearAlgUtil::MatrixMultiply4X4(int M1[][4], int M2[][4], int Result[][4])
{
	cout << "Now executing LinearAlgUtil::MatrixMultiply4X4 function.\n";
}

//-------------------------------------------------------
// Rotate a point in 2D using pointer to Point2D struct
//-------------------------------------------------------
void LinearAlgUtil::RotatePoint2D_Ptr(Point2D *pt, double angle)
{
	cout << "Now executing LinearAlgUtil::RotatePoint2D_Ptr function.\n";
}

//-------------------------------------------------------
// Rotate a point in 2D using reference to Point2D struct
//-------------------------------------------------------
void LinearAlgUtil::RotatePoint2D_Ref(Point2D& pt, double angle)
{
	cout << "Now executing LinearAlgUtil::RotatePoint2D_Ref function.\n";
}
			

Output from running the Sprint 1 code







Sprint 2 Code

Below you will see the final code created for this demonstration project during Sprint 2.
Note carefully the comments on testing given in the file with main().
There is also an image of the on-screen output after a run of the compiled program.

File: Prog1Main.cpp


//=============================================================================
// Programming Assignment Demonstration
// File: Prog1Main.cpp
// This program demonstrates the steps to be completed in Sprint 2.
//
//
// Author: Dr. Rick Coleman
// History: Project created December 2015
//=============================================================================
#include "LinearAlgUtil.h"
#include <math.h>
#include <iomanip>
#include <iostream>

using namespace std;

#define SPRINT2

void main()
{
	int vect1[3];		// Array of 3 ints to represent a vector in XYZ space
	int vect2[3];		// Array of 3 ints to represent a vector in XYZ space
	int vectResult[3];	// Array of 3 ints to represent a vector in XYZ space

	int matrix1[4][4];	// 2-D Array of ints to represent a matrix
	int matrix2[4][4];	// 2-D Array of ints to represent a matrix
	int matrixResult[4][4];	// 2-D Array of ints to represent a matrix

	Point2D pt;		// Structure for testing point rotate functions

	int testResult = 0; 	// Keep up with count of successful tests
	int expectedResult = 0;

	LinearAlgUtil *lau = new LinearAlgUtil();	// Create test instance

	// Test the DotProduct function
	vect1[0] = 1;	// Init vector 1 to (X, 2Y, 3Z)
	vect1[1] = 2;
	vect1[2] = 3;
	vect2[0] = 4;	// Init vector 2 to (4X, 5Y, 6Z)
	vect2[1] = 5;
	vect2[2] = 6;
	// Call DotProcuct function
	int dotResult = lau->DotProduct(vect1, vect2);
	// Expected result = (1x4)+(2*5)+(3*6) = 32
	cout << "\nTest of DotProduct:  Expected 32, got back " << dotResult << endl;
	if(dotResult == 32)
	{
		cout << "Test successful\n";
		testResult++;	// Increment success counter
	}
	else
		cout << "Test failed\n";
	expectedResult++;	// Increment test counter

	// Test the CrossProduct function
	// Use same vectors defined in test of DotProduct
	lau->CrossProduct(vect1, vect2, vectResult); // Call CrossProduct function
	// Expected result        1   2   3          4   5   6
	// Given two vectors:  a=(a0, a1, a2) and b=(b0, b1, b2)
	//       vect1 x vect2  = (a1b2 - a2b1), (a2b0 - a0b2), (a0b1 - a1b0)
	//			= (2*6 - 3*5), (3*4 - 1*6), (1*5 - 2*4)
	//			= (-3, 6, -3)
	cout << "\nTest of CrossProduct got back: (" << vectResult[0] << ", " << vectResult[1] << ", " << vectResult[2] << ")\n";
	if((vectResult[0] == -3) && (vectResult[1] == 6) && (vectResult[2] == -3))
	{
		cout << "Test successful\n";
		testResult++;	// Increment success counter
	}
	else
		cout << "Test failed\n";
	expectedResult++;	// Increment test counter

	// Test the MatrixMultiply4X4 function
	// Build 2 test matrices	|  1  2  3  4|		|17 18 19 20|
	//			    A = |  5  6  7  8|      B = |21 22 23 24|
	//				|  9 10 11 12|		|25 26 27 28|
	//				| 13 14 15 16|		|29 30 31 32|
	for(int row=0; row<4; row++) // For each row in the resulting matrix
	{
		for(int col=0; col<4; col++) // For each column in the resulting matrix
		{
			matrix1[row][col] = (row * 4) + col + 1;
			matrix2[row][col] = matrix1[row][col] + 16;
			matrixResult[row][col] = 0;  // clear this one
		}
	}
	// Manually calculate the result of A * B
	//	C00 = ( 1 * 17) + ( 2 * 21) + ( 3 * 25) + ( 4 * 29) = 250
	//	C01 = ( 1 * 18) + ( 2 * 22) + ( 3 * 26) + ( 4 * 30) = 260
	//	C02 = ( 1 * 19) + ( 2 * 23) + ( 3 * 27) + ( 4 * 31) = 270
	//	C03 = ( 1 * 20) + ( 2 * 24) + ( 3 * 28) + ( 4 * 32) = 280
	//
	//	C10 = ( 5 * 17) + ( 6 * 21) + ( 7 * 25) + ( 8 * 29) = 618
	//	C11 = ( 5 * 18) + ( 6 * 22) + ( 7 * 26) + ( 8 * 30) = 644
	//	C12 = ( 5 * 19) + ( 6 * 23) + ( 7 * 27) + ( 8 * 31) = 670
	//	C13 = ( 5 * 20) + ( 6 * 24) + ( 7 * 28) + ( 8 * 32) = 696
	//
	//	C20 = ( 9 * 17) + (10 * 21) + (11 * 25) + (12 * 29) = 986
	//	C21 = ( 9 * 18) + (10 * 22) + (11 * 26) + (12 * 30) = 1028
	//	C22 = ( 9 * 19) + (10 * 23) + (11 * 27) + (12 * 31) = 1070
	//	C23 = ( 9 * 20) + (10 * 24) + (11 * 28) + (12 * 32) = 1112
	//
	//	C30 = (13 * 17) + (14 * 21) + (15 * 25) + (16 * 29) = 1354
	//	C31 = (13 * 18) + (14 * 22) + (15 * 26) + (16 * 30) = 1412
	//	C32 = (13 * 19) + (14 * 23) + (15 * 27) + (16 * 31) = 1470
	//	C33 = (13 * 20) + (14 * 24) + (15 * 28) + (16 * 32) = 1528
	//
	// This gives the matrix:	|  250  260  270  280|
	//			   C =  |  618  644  670  696|
	//				|  986 1028 1070 1112|
	//				| 1354 1412 1470 1528|

	lau->MatrixMultiply4X4(matrix1, matrix2, matrixResult); // Call MatrixMultiply4X4 function
	// Test results
	bool mmOK = true;
	// Check row 0	|  250  260  270  280|
	if(matrixResult[0][0] != 250) mmOK = false;
	if(matrixResult[0][1] != 260) mmOK = false;
	if(matrixResult[0][2] != 270) mmOK = false;
	if(matrixResult[0][3] != 280) mmOK = false;
	// Check row 1	|  618  644  670  696|
	if(matrixResult[1][0] != 618) mmOK = false;
	if(matrixResult[1][1] != 644) mmOK = false;
	if(matrixResult[1][2] != 670) mmOK = false;
	if(matrixResult[1][3] != 696) mmOK = false;
	// Check row 2	|  986 1028 1070 1112|
	if(matrixResult[2][0] != 986) mmOK = false;
	if(matrixResult[2][1] != 1028) mmOK = false;
	if(matrixResult[2][2] != 1070) mmOK = false;
	if(matrixResult[2][3] != 1112) mmOK = false;
	// Check row 3	| 1354 1412 1470 1528|
	if(matrixResult[3][0] != 1354) mmOK = false;
	if(matrixResult[3][1] != 1412) mmOK = false;
	if(matrixResult[3][2] != 1470) mmOK = false;
	if(matrixResult[3][3] != 1528) mmOK = false;
	if(matrixResult)
	{
		cout << "\nTest of MatrixMultiply4x4 successful\n";
		testResult++;	// Increment success counter
	}
	else
		cout << "\nTest of MatrixMultiply4x4 Test failed\n";
	expectedResult++;	// Increment test counter

	// Test the RotatePoint2D_Ptr function
	pt.x = 5.0;
	pt.y = 0.0;
	bool ptRot = true;
	// Test Note:  Because the rotation must work in all 4 quadrants this must be
	//				tested in all four quadrants.
	// Perform rotation of point (5, 0) to 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330 degrees
	for(int i=0; i<360; i+=30)
	{
		lau->RotatePoint2D_Ptr(&pt, (double)i); // Call RotatePoint2D_Ptr function
		// Check the output
		// This should create triangles with hypotenuse of 5 and other 2 sides of 4.3 and 2.5
		// Note: The results below were obtained by calculating the two sides of a triangle with 
		//			hypotenuse of 5 and angles of 30, 60, 90 degrees with the X and Y sides on
		//			the X and Y axes.
		switch(i)
		{
			case 0 : if((pt.x != 5.0) && (pt.y != 0.0)) ptRot = false; break;
			case 30 : if((pt.x != 4.3) && (pt.y != 2.5)) ptRot = false; break;
			case 60 : if((pt.x != 2.5) && (pt.y != 4.3)) ptRot = false; break;
			case 90 : if((pt.x != 0.0) && (pt.y != 5.0)) ptRot = false; break;
			case 120 : if((pt.x != -2.5) && (pt.y != 4.3)) ptRot = false; break;
			case 150 : if((pt.x != -4.3) && (pt.y != 2.5)) ptRot = false; break;
			case 180 : if((pt.x != -5.0) && (pt.y != 0.0)) ptRot = false; break;
			case 210 : if((pt.x != -4.3) && (pt.y != -2.5)) ptRot = false; break;
			case 240 : if((pt.x != -2.5) && (pt.y != -4.3)) ptRot = false; break;
			case 270 : if((pt.x != 0.0) && (pt.y != -5.0)) ptRot = false; break;
			case 300 : if((pt.x != 2.5) && (pt.y != -4.3)) ptRot = false; break;
			case 330 : if((pt.x != 4.3) && (pt.y != -2.5)) ptRot = false; break;
		}
		// Reset xy for next rotation
		pt.x = 5.0;
		pt.y = 0.0;
	}
	if(ptRot)
	{
		cout << "\nTest of RotatePoint2D_Ptr successful\n";
		testResult++;	// Increment success counter
	}
	else
		cout << "\nTest of RotatePoint2D_Ptr Test failed\n";
	expectedResult++;	// Increment test counter

	// Test the RotatePoint2D_Ref function
	// This is the same test as for RotatePoint2D_Ptr.  The only difference is that this
	//   function is passed a reference to the Point2D structure while in the previous
	//   function a pointer was passed.
	pt.x = 5.0;
	pt.y = 0.0;
	ptRot = true;
	// Test Note:  Because the rotation must work in all 4 quadrants this must be
	//				tested in all four quadrants.
	// Perform rotation of point (5, 0) to 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330 degrees
	for(int i=0; i<360; i+=30)
	{
		lau->RotatePoint2D_Ref(pt, (double)i); // Call RotatePoint2D_Ref function
		// Check the output
		// This should create triangles with hypotenuse of 5 and other 2 sides of 4.3 and 2.5
		// Note: The results below were obtained by calculating the two sides of a triangle with 
		//			hypotenuse of 5 and angles of 30, 60, 90 degrees with the X and Y sides on
		//			the X and Y axes.
		switch(i)
		{
			case 0 : if((pt.x != 5.0) && (pt.y != 0.0)) ptRot = false; break;
			case 30 : if((pt.x != 4.3) && (pt.y != 2.5)) ptRot = false; break;
			case 60 : if((pt.x != 2.5) && (pt.y != 4.3)) ptRot = false; break;
			case 90 : if((pt.x != 0.0) && (pt.y != 5.0)) ptRot = false; break;
			case 120 : if((pt.x != -2.5) && (pt.y != 4.3)) ptRot = false; break;
			case 150 : if((pt.x != -4.3) && (pt.y != 2.5)) ptRot = false; break;
			case 180 : if((pt.x != -5.0) && (pt.y != 0.0)) ptRot = false; break;
			case 210 : if((pt.x != -4.3) && (pt.y != -2.5)) ptRot = false; break;
			case 240 : if((pt.x != -2.5) && (pt.y != -4.3)) ptRot = false; break;
			case 270 : if((pt.x != 0.0) && (pt.y != -5.0)) ptRot = false; break;
			case 300 : if((pt.x != 2.5) && (pt.y != -4.3)) ptRot = false; break;
			case 330 : if((pt.x != 4.3) && (pt.y != -2.5)) ptRot = false; break;
		}
		// Reset xy for next rotation
		pt.x = 5.0;
		pt.y = 0.0;
	}
	if(ptRot)
	{
		cout << "\nTest of RotatePoint2D_Ref successful\n";
		testResult++;	// Increment success counter
	}
	else
		cout << "\nTest of RotatePoint2D_Ref Test failed\n";
	expectedResult++;	// Increment test counter

	// Output result of testing
	cout << "\nFinal result of testing = " << testResult << endl;
	cout << "Expected to get a count of " << expectedResult << endl << endl;
}
			


File: LinearAlgUtil.h


//=======================================================================
// LinearAlgUtil.h
// Header file defining a class of Linear Algebra Utility functions.
//   This program is a demonstration for programming assignments in
//   CS 221 following the Agile approach of Scrum.
//
// Author: Dr. Rick Coleman
// History: Created December 2015
//=======================================================================
#pragma once;

// Define the point structure
struct Point2D
{
	double x;
	double y;
};

class LinearAlgUtil
{
	private:
		Point2D m_Pt;	// Temp Point2D struct for use by point rotate functions

	public:
		LinearAlgUtil();						// Default constructor
		~LinearAlgUtil();					// Destructor
		int DotProduct(int u[], int v[]);			// Calculate the Dot Product of vectors u and v
		void CrossProduct(int u[], int v[], int Result[]);	// Calculate the Cross Product of vectors u and v
		void MatrixMultiply4X4(int M1[][4], int M2[][4], int Result[][4]);// Calculate a 4x4 matrix multiplication
		void RotatePoint2D_Ptr(Point2D *pt, double angle);	// Rotate a point in 2D using pointer to Point2D struct
		void RotatePoint2D_Ref(Point2D& pt, double angle);  	// Rotate a point in 2D using reference to Point2D struct
};
			


File: LinearAlgUtil.CPP

//===========================================================================
// LinearAlgUtil.cpp
// Implementation file defining a class of Linear Algebra Utility functions.
//   This program is a demonstration for programming assignments in
//   CS 221 following the Agile approach of Scrum.
//
// This file demonstrates the implementation to be completed in Sprint 2.
// Author: Dr. Rick Coleman
// History: Created December 2015
//===========================================================================
#include "LinearAlgUtil.h"
#include <math.h>

//------------------------------------------------
// Default constructor
//------------------------------------------------
LinearAlgUtil::LinearAlgUtil()
{
	// Nothing to do in the constructor.
	// It was tested in Sprint 1
}

//------------------------------------------------
// Destructor
//------------------------------------------------
LinearAlgUtil::~LinearAlgUtil()
{
	// Nothing to do in the destructor
	// It was tested in Sprint 1
}

//-------------------------------------------------------
// Calculate the Dot Product of vectors u and v
//
// Given two vectors:  a=(a0, a1, a2) and b=(b0, b1, b2)
//   a dot b = a0b0 + a1b1 + a2b2.
//-------------------------------------------------------
int LinearAlgUtil::DotProduct(int u[], int v[])
{
	int dp;
	dp = (u[0] * v[0]) + (u[1] * v[1]) + (u[2] * v[2]);
	return dp;
}

//-------------------------------------------------------
// Calculate the Cross Product of vectors u and v
// Given two vectors:  a=(a0, a1, a2) and b=(b0, b1, b2)
//   a x b = (a1b2 - a2b1), (a2b0 - a0b2), (a0b1 - a1b0)
//-------------------------------------------------------
void LinearAlgUtil::CrossProduct(int u[], int v[], int Result[])
{
	// Calculate and store (a1b2 - a2b1)
	Result[0] = (u[1] * v[2]) - (u[2] * v[1]);
	// Calculate and store (a2b0 - a0b2)
	Result[1] = (u[2] * v[0]) - (u[0] * v[2]);
	// Calculate and store (a0b1 - a1b0)
	Result[2] = (u[0] * v[1]) - (u[1] * v[0]);
}

//-------------------------------------------------------
// Calculate a 4x4 matrix multiplication
// Given:    |a00 a01 a02 a03|   |b00 b01 b02 b03|
//			 |a10 a11 a12 a13|   |b10 b11 b12 b13|
//			 |a20 a21 a22 a23| x |b20 b21 b22 b23|
//			 |a30 a31 a32 a33|   |b30 b31 b32 b33|
// Each element in the resulting 4x4 matrix is found by
//   accessing the corresponding row in matrix A with the
//   corresponding column of matrix B. Thus the element
//   in position (0,0) is found with:
//   c00 = a00*b00 + a01*b10 + a02*b20 + a03*b30;
//	The element in position (3,3) is found with:
//   c33 = a30*b03 + a31*b13 + a32*b23 + a33*b33;
//-------------------------------------------------------
void LinearAlgUtil::MatrixMultiply4X4(int M1[][4], int M2[][4], int Result[][4])
{
	for(int row=0; row<4; row++) // For each row in the resulting matrix
	{
		for(int col=0; col<4; col++) // For each column in the resulting matrix
		{
			Result[row][col] = (M1[row][0] * M2[0][col]) + (M1[row][1] * M2[1][col]) +
				(M1[row][2] * M2[2][col]) + (M1[row][3] * M2[3][col]);
		}
	}
}

//------------------------------------------------------------
// Rotate a point in 2D using pointer to Point2D struct
// This uses the matrix for rotating points about the Z axis
//   and matrix multiplication.
//				| cos A     -sin A|    |X|
//				| sin A      cos A|  * |Y|
// Note: Because of some slight idiocyncracies in precision
//   point coordinates are being rounded to the nearest 10th
//   of a unit which for the purposes of this application is
//	 still more accuracy than is required.
//------------------------------------------------------------
void LinearAlgUtil::RotatePoint2D_Ptr(Point2D *pt, double angle)
{
	// Copy the structure before rotating
	m_Pt = *pt;
	// Convert angle in degrees to radians (math functions require this)
	// Angle in Radians = Angle in Degrees * PI/180 (0.0174532925)
	double radDeg = angle * 0.01745;
	pt->x = (m_Pt.x * cos(radDeg)) - (m_Pt.y * sin(radDeg));
	pt->y = (m_Pt.x * sin(radDeg)) + (m_Pt.y * cos(radDeg));
	// Now round to 2 decimal places
	int temp = (int)floor((pt->x * 10.0) + 0.5);
	pt->x = (double)temp / 10.0;
	temp = (int)floor((pt->y * 10.0) + 0.5);
	pt->y = (double)temp / 10.0;
	// FYI: I know it looks weird but there is no round function in math.h
	//  If rounding to the nearest 10th, then any value from 4.45 to 4.54 must round to 4.5
	//  Example:  Assume pt.x is 4.45678.  Multiply by 10 to get 44.5678.
	//  If you took the floor of this you get 44 then divide by 10 to get 4.4
	//  which is not the value you needed.  But if you add 0.5 to 44.5678 you
	//  get 45.0678.  Now take the floor of this to get 45 and divide by 10
	//  to get 4.5.  This then gives the accurate value 4.45678 rounded to the
	//  nearest 10th.
}

//-------------------------------------------------------
// Rotate a point in 2D using reference to Point2D struct
// This uses the matrix for rotating points about the Z axis
//   and matrix multiplication.
//				| cos A     -sin A|    |X|
//				| sin A      cos A|  * |Y|
// Note: Because of some slight idiocyncracies in precision
//   point coordinates are being rounded to the nearest 10th
//   of a unit which for the purposes of this application is
//	 still more accuracy than is required.
//-------------------------------------------------------
void LinearAlgUtil::RotatePoint2D_Ref(Point2D& pt, double angle)
{
	// Copy the structure before rotating
	m_Pt = pt;
	// Convert angle in degrees to radians (math functions require this)
	// Angle in Radians = Angle in Degrees * PI/180 (0.0174532925)
	double radDeg = angle * 0.01745;
	pt.x = (m_Pt.x * cos(radDeg)) - (m_Pt.y * sin(radDeg));
	pt.y = (m_Pt.x * sin(radDeg)) + (m_Pt.y * cos(radDeg));
	// Now round to 2 decimal places
	int temp = (int)floor((pt.x * 10.0) + 0.5);
	pt.x = (double)temp / 10.0;
	temp = (int)floor((pt.y * 10.0) + 0.5);
	pt.y = (double)temp / 10.0;
	// FYI: I know it looks weird but there is no round function in math.h
	//  If rounding to the nearest 10th, then any value from 4.45 to 4.54 must round to 4.5
	//  Example:  Assume pt.x is 4.45678.  Multiply by 10 to get 44.5678.
	//  If you took the floor of this you get 44 then divide by 10 to get 4.4
	//  which is not the value you needed.  But if you add 0.5 to 44.5678 you
	//  get 45.0678.  Now take the floor of this to get 45 and divide by 10
	//  to get 4.5.  This then gives the accurate value 4.45678 rounded to the
	//  nearest 10th.
}
			

Output from running the Sprint 2 code












A programming assignment about Linear Algebra!


But, Dr. Coleman, I haven't taken Linear Algebra.
How can you expect me to do this programming
assignment. This is sooooooo unfair.

Welcome to the real world of Software Engineering. In this example programming assignment Linear Algebra is known as the application Domain. That is, the specific subject matter, of the application. As a professional software engineer you will find many times you will get a contract from a customer or business about which you know nothing. It will then be your responsibility to become familiar with the customer's Domain. In the course of his career your instructor had to become educated in such diverse Application Domains as battle field tactics, how first responders handle emergency situations, how the petroleum industry drills for oil and what information they get from sensors on the wells, and several other areas.