This is more involved than other extensions, so this perspective projection extension counts as two (2) extension credits. It's a challenge, but the directions are specific and success is pleasing.
This extension was prepared for CSE131 when the class had 4 lectures per week. There is no time in class to cover this topic in the current format for CSE131, so you are on your own if you want to undertake this extension.
You will be required to defend your design and implementation to the instructor to receive the credits for this extension.
In this extension, you will implement an application that allows a user to view a perspective projection of a 3D scene from different vantage points by interacting with three sliders that control the viewer's distance from the center of the scene and the viewer's latitude and longitude on an imaginary sphere around the image, where the radius of the sphere is defined by the viewer's distance. When finished, your application will look something like this:
The last method provides a conversion between two representations of the point in order to simplify multiplying point by a matrix for the perspective projection calculation. Point3D is immutable because it has no mutating methods. So, to avoid creating multiple matrices for the same point, you can create its 4-by-1 matrix once within the Point3D constructor, and return that same matrix each time toMatrix is called.
Optional but recommended: For your convenience in creating scenes, you may want to add methods to your Scene class that support adding lines relative to a "current position," like a 3D etch-a-sketch. To accomplish this, you'll need an instance variable (of type Point3D) to keep track of the current position. Useful methods include (1) a moveTo method that sets the current position to a given point without creating a line, (2) a lineTo method that creates a line from the current position to a destination point, and sets the current position to that destination, (3) a moveBy method that shifts the current position by a given Vector3D without creating a line, and (4) a lineBy method that is the same as moveBy except that it also creates a line from the old to the new current position.
Design notes: The projector will use the 3D projection algorithm presented in class to obtain a perspective projection of the scene. Internally, the projector will need to keep the four matrices (perspective, scale, rotation, and translation) in instance variables. When the distance, latitude, or longitude of the vantage point are changed, the projector should recompute these matrices as needed. For example, when setLatitude is called, the rotation and translation matrices need to be recomputed since they depend upon the latitude. You'll also want to update the combined matrix PSRT. We recommend creating private methods for recomputing each of those matrices, and for updating PSRT by multiplying them. Also, to simplify the method that projects an entire scene, it's a good idea to write a method that will project a single point. Then you can call that method on each endpoint of each line in the scene.
Mathematics note: Some of matrices in the calculations involve near and far, which correspond to the distances from the viewer to the two planes that "bracket" the scene. You will create a scene using coordinates in the range -1 to 1. Since the viewing distance is measured from (0,0,0) at center of the scence, we can be sure that the scene is bracketed by the near and far planes if we always let near be distance-2 and far be distance+2.
The central "glue" for system integration will be a YOPS tool that creates a scene and accepts user input (through sliders) to update the projected image of that scene. The tool will use the Scene class and the Projector class, which each use various other components you have created.
Open the provided file SceneTool.java. Note that this class includes the main method for your program, so this is the class you will run. Modify SceneTool as follows to complete the integration of your application.
Make an appointment with the instructor to defend and demo your design and implementation.