For the second task, we had to build all of the user control capabilities.
The first one we made was the handleButton1 method, which let us press the left mouse/trackpad button and lead into the handleButton1Motion if we moved. For this motion method, we followed a provided algorithm. For this, we first calculated the difference in former and current position, allowing us to get the distance moved. With this, we could get the delta x and delta y, which were scaled to the screen by being divided by the screen height then being multiplied by the current extent. Then, we calculated the new vrp, updated the axes, and replaced the self.baseclick location.
The second function we made was to have the button 3 of the mouse implement scaling. Moving up makes the items come closer, and moving down makes them appear farther away. As before, we calculated the distance moved, but this time, we calculated a scale factor, as well. This would be multiplied by the base extent to determine the new extent. Therefore, it had to start at 1 to ensure the extent remained the same by default, and since it should range from .1 to 3 times the original view size, I subtracted no more than the amount moved divided by the screen size, and added no more than 3 times the amount moved divided by the screen size.
The third subtask concerned making the pipeline for rotation around the view volume in the view class. We made a series of matrices - one to translate, one to align, one to rotate about y, one to rotate about x, one to unalign, and one to represent the starting, untranslated view reference coordinates. We multiply them all in the end, and then reassign the results to vrp, u, vup, and vpn, and normalize them all at the end.
The last part of task 2 was to give the user the ability to utilize this method. They would press button 2 on the mouse, and moving the mouse around would give the mousebutton2 motion-handling method the amount moved, which it would use to calculate the angle (math.pi*((difference)/200)). Then we use the original view matrix and transform that using the angles as input to the view class's rotation method.
My first extension was to implement a reset button. I simply linked the spacebar to a method that calls the reset method of view, which resets all the matrices, and then updates the axes to reflect that change.