ITP 168: Introduction to MATLAB
Homework 5 Due: 11:59pm April 16, 2021
In this homework you will be exploring a topographical map using your keyboard. I will give you several files for you to explore, or you can create them yourself here
In this homework, I give you a file to work with, only because it has special code in it that is required for you to use the keyboard to interact with the plot. Only add code where it says to add code and DO NOT change the code already written.
- You are given a file named exploremap.m which will be a function file
- Create a script file named: mapExplorer.m
- Using comments, put the following information at the top of the script file, and after the
function definition and H1 line of the function file:
o ITP 168 Spring 2021 o Homework 5
o USC Email
Include the clear, clc, and close all commands in the script file
Part 1: Script File
The script file should ask the user for the name of the file in which the data is stored. If the file does not exist in the current folder, let the user know that the file could not be found, and ask them for a different file.
Consider using the isfile function.
Once the filename has been validated, read in the file. Every file that I supply has the same format.
- The files are space-delimited files
- The first row of the file contains TWO values: the number of rows and the number of columns of
the final array used to create the maps
- After the first row are 3 column vectors: longitude, latitude, and elevation
Longitude is measured from the prime meridian eastward (0 – 360) in degrees. Latitude is measured from the equator (north is positive, south is negative) in degrees. Elevation is given in meters.
Given the filename, load the data from the file.
Once the data has been loaded, you will have to reshape the column vectors so they are arrays of the same size. To perform the reshape, use the reshape function to reshape the column vectors into arrays. The dimensions of the arrays are given as the first row of the data file.
Once the data has been reshaped, call the exploremap function with the correct inputs. Part 2: exploremap() Setup
The exploremap function has the following function definition:
- Outputs: none
- Inputs: 3 arrays: longitude, latitude, elevation
Validate the input: all three must be numeric arrays of the same size.
To accurately plot the surface of the Earth to scale, we have to standardize the units. Longitude and latitude are given in degrees, but elevation is given in meters. Since this is a small enough slice of the Earth we make use of small angle approximations and the radius of the Earth.
Here we have an angle θ, and a radius A (which is the radius of the earth), and we are trying to find O, the representative distance of an angle θ. To do so, we can say that:
𝑂 ≅ 𝐴 tan 𝜃
We say it’s an approximation because we know that the earth is actually curved and follows the path denoted by s instead of O. But for small angles, this is a good approximation. The radius of the earth is 6.371 million meters. Now that we know this, we will convert our latitude and longitude values to meter values.
In order to do that we must determine the angle DIFFERENCES between each value. I want to calculate what the angle is between the two angles so I know what the distance is between the two points on the map in meters.
Our converted values will be stored in another vector and have starting points of X = 0 and Y = 0. Each element after that will be the distance from the starting point of 0.
- Create two arrays the same size as the latitude and longitude arrays with only zero values within it
- We will do LONGITUDE conversion first:
a. Create a loop that starts off at index 2 and stops at an index equal to the number of
columns in the longitude
i. The columns of the longitudinal array will have the same values for every element. The equation to determine the meter values for the longitudinal array for any given value of index is as follows
1. longMeters(:,index) = longMeters(:,index – 1) + radiusOfEarth*tan(longDeg(:,index) – longDeg(:,index-1));
ii. LONG values are in degrees! Does this change the equation?
Using the same idea, convert the latitude degree values to meter values. The rows of the latitude value array will have the same values for every element. (Do not just copy the same loop/equation).
Part 3: exploremap Plot
Now that the data is in the correct format, we want to show the entire map as a contour plot, and also show a sub-section of the map as a surface plot. A sample of what the plot should look like is given below.
On the left is the surface plot showing a portion of the whole map. On the right is a contour plot showing the whole map, and a red box that shows the area of the map displayed in the surface plot.
Using subplots, draw the surface and the contour plot side-by-side. For the surface plot, plot the ENTIRE surface, but use the xlim() and ylim() functions to limit what you actually see to only be the area bounded by the box. For the contour plot, plot the ENTIRE contour.
Part 4: Plotting the Boundary Box
The red box on the contour plot is made by plotting lines on top of the contour. To plot the box, we will determine which rows and columns define the boundaries of the box. Imagine the data like the following grid:
Col 1 Row 1
Col 9 Row 6
The surface is given by the red patch, which is bounded by Row 6, Row 13, Col 9, and Col 16. Since the data for the surface and contour is given by meter values, we will use the row and column values of the boundary box to refer to the rows and columns of the meter arrays.
Set a value for the size of the boundary box. This should be an integer value as it will refer to the number of rows and columns to span for the box size. In the grid example above the boundary box size is 8 (it spans rows 6-13, and columns 9-16). A good boundary box size to use is somewhere between 20- 30.
Set the initial boundary box to start at the first row and first column and extend down the rows and across the columns. You should probably keep track of which row and column will start and end the boundary box.
Set a value for the move size, the number of rows or columns to move each time the user moves the boundary box. This should be a small integer value (less than the boundary box size). A good value to use is 5.
Plot the initial boundary box using the meter values of the longitude and latitude combined with the row and column values of the boundary box. Make a plot handle for the boundary box plot because you will have to animate it later.
Use the command axis equal on the contour plot so that the map is not skewed.
You should see the contour plot AND the boundary box on the same axes. You should see the boundary
box appear in the UPPER LEFT corner of the plot like the figure shown below:
Part 5: exploremap() Explore
Now that the initial plots are set, you need to be able to interact with the map by pressing the W, A, S, and D keys. Within the loop, you will have to code the movement of the boundary box as well as the updating of the surface plot.
When the user presses the ‘s’ key, they want to move south on the map. South means the boundary box moves down. Which means that the rows are increasing. If the user moves too far south (the edge of the map), be sure they stop at the last row. Each time the user presses the ‘s’ key, it should move the boundary box south by the move size.
When the user presses the ‘w’ key, they want to move north on the map. North is up. Be sure the user cannot go too far north (the top edge of the map) and they stop at the first row.
When the user presses the ‘a’ or ‘d’ key, they want to move west or east respectively. West and east are left and right respectively. Be sure the user cannot move too far off the map (the edges) and stay within the first column and the last column.
Each time the user moves, keep track of the starting and ending row and column values.
Update the boundary box plot using the updated values of the starting and ending row and column values and the longitude and latitude meter values. For the surface plot, use the xlim and ylim functions
to change the X and Y limits of the surface plot to show the updated surface bounded by the boundary box. The values given to the functions must be in ascending order.
Since the output is complex, a demo will be given in class. If you want to create your own map to explore, I have provided a function to take in the file created by the link given in the setup so that the files you create are in the correct format for reading.
Create a .ZIP file containing the file(s): mapExplore.m
Name it Homework5.ZIP and submit it to Blackboard by the due date. Grading Rubric:
Script File 10 Points exploremap Plot 8 Points exploremap Explore 10 Points
*Points will be taken off for poor coding style for a maximum of 1-point deduction
**Up to 2 points will be taken off for not submitting a ZIP file
***Intentional instantiation of an infinite loop will result in an automatic 10% deduction of total points for each occurrence.
exploremap Boundary Box