A 2000 Rose-Hulman graduate named Deming Speed has already made his millions, and after retiring to his lifelong-dream-community of Terre Haute, he plans to take a special trip. He wants to visit several of the largest cities of the world (largest populations, according to the 1993 World Almanac). The question he thinks about in his life of leisure is, "In what order should I visit them?" He has come up with several possible schemes. Two of them are
1) Alphabetical order.
2) In order from northernmost to southernmost
For each visitation order, Deming wants to know the total number of miles that he will fly if he starts in the first city and travels to each of the remaining largest cities in the given order, stopping at the last city. You have been hired to find out this information for him.
Because Mr. Speed owns his own fleet of planes, you may assume that there is always a direct flight from city to city wherever needed. Because Deming is so well-loved all over the world, every country lets him fly through their airspace. This means that the distance between cities is the "great circle" distance.
You have been provided with the city names (in the file
cities.dat
)
along with their latitudes and
longitudes (in degrees, minutes, and direction). In a second file
called simple.dat
, we have shown some fake cities for which it should be
easy to calculate the distances by hand to check your program's answers.
The base code and data files for this program is in the AroundTheWorld
project in your individual SVN repository.
We have also placed in your repository a working project called TestScores
.
Studying the code in that project may help you see how to do some of the things
you need to do for this one. We recommend that you run that code and spend
some time understanding it before writing your code for this project.
For each of the two possible routes, you should print a table with one line per destination city (in the order in which the cities are visited). Each line should list (at least) the name of the city, its location (latitude and longitude), the number of miles flown to reach this city from the previous city, and an accumulated distance flown so far on the entire trip. On the first line, the accumulated distance will be 0. Format the table for easy readability.
Print the names of the two closest cities from the input file.
In addition to the printing the above information, you should also provide a menu that allows the user to interactively choose any two cities from the list; the program then calculates and prints the distance (in miles) between those cities. You may want to write this part of the code first, so you can test your distance function before working on sorting and producing the tables.
Your program should be written in such a way that it can handle any number of cities up to 100. It should determine how many cities to use from what it reads in the data file.
You should define a city
structure type with fields for each of the data
items that your program needs to remember about an individual city. Then you will
need an array of city
s.
This is an individual project. You are allowed to get
help from other people, but the code you turn in should be written and understood
by you.
Commit your completed code to your repository.
You will need a function that takes two cities as arguments and
calculates the surface distance between them. Test your function by
computing and printing the distance between some cities, starting with
the ones in simple.dat
.
The earth is not a perfect sphere, but for the purpose of this problem you may pretend that it is a sphere. The average of the polar and equatorial radii of the Earth is 3957 miles; use that number.
Using the following website, you can calculate the distance between many pairs of cities, to help you check the results of your function.
http://www.chemical-ecology.net/java/lat-long.htm
You are welcome to use the calculations from that web site (written in JavaScript language) to help you write your C code. Then you do not have to figure out all of the mathematics behind the calculations. If you find this code hard to read, feel free to use more descriptive variable names:
function caldist(form) { var er = 3957
// Convert latitudes to radians
var radlat1 = Math.PI * (td[nq] + tm[nq]/60 + ts[nq]/3600)/180 var radlat2 = Math.PI * (td[nj] + tm[nj]/60 + ts[nj]/3600)/180 //Convert longitudes to radians var radlong1 = Math.PI * (gd[nq] + gm[nq]/60 + gs[nq]/3600)/180 var radlong2 = Math.PI * (gd[nj] + gm[nj]/60 + gs[nj]/3600)/180 //spherical coordinates x=r*cos(ag)sin(at), y=r*sin(ag)*sin(at), z=r*cos(at) //zero ag is up so reverse lat if (tr[nq]=="N") {radlat1=Math.PI/2-radlat1} if (tr[nq]=="S") {radlat1=Math.PI/2+radlat1} if (gr[nq]=="W") {radlong1=Math.PI*2-radlong1} if (tr[nj]=="N") {radlat2=Math.PI/2-radlat2} if (tr[nj]=="S") {radlat2=Math.PI/2+radlat2} if (gr[nj]=="W") {radlong2=Math.PI*2-radlong2} var x1 = er * Math.cos(radlong1)*Math.sin(radlat1) var y1 = er * Math.sin(radlong1)*Math.sin(radlat1) var z1 = er * Math.cos(radlat1) var x2 = er * Math.cos(radlong2)*Math.sin(radlat2) var y2 = er * Math.sin(radlong2)*Math.sin(radlat2) var z2 = er * Math.cos(radlat2) var d = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)) //side, side, side, law of cosines and arc cosine var theta = Math.acos((er*er+er*er-d*d)/(2*er*er)) var distance = theta*er //arc length is radius times angle.
Each line of the input file will contain
a city name: columns 1-20 (if the name is shorter than that, there
will be trailing spaces, to bring the total length to 20).
the latitude
degrees: columns 22-23
minutes: columns 25-26
direction: column 28 (will be N or S)
the longitude
degrees: columns 30-32
minutes: columns 34-35
direction: column 37 (will be E or W)
You may want to define a struct type to represent a coordinate (latitude
or longitude), which holds degrees, minutes, and direction. Two of
these coordinate structs can then be fields of your city
struct type.
You may also wish to include some calculated information in your
city
structure definition, to avoid repeated recalculation.
We found that float sometimes loses some accuracy. Feel free to use type double instead of float in your calculations for more accurate results.
You may earn up to 25 additional points for some creative enhancement, some other interesting thing(s) to do with this data. If you do this, it should appear in your output after the required output. The number of bonus points will depend on quality of your enhancement idea (in your instructor's opinion) and correctness of your implementation of that idea. For example, visiting the cities in order of distance from Indianapolis (shortest distance to longest distance) would be worth 10 points. (The latitude of Indianapolis is 39� 46' N, and the longitude is 86� 9' W.)