This lab will develop your skills in calling and writing functions.
This page will be available as
http://www.tricity.wsu.edu/~bobl/cpts121/lab05_functions/writeup.html
Calling it up in a browser will allow you to cut-and-paste the templates below into your editor and save editing time.
Plug your thumbdrive into your workstation and, in a MinGW terminal emulator, create a new directory for this lab and cd to it:
$ cd /e/cpts121 $ mkdir lab05 $ cd lab05
As before, keep all your work in this directory.
We'll develop a program crow_fly that computes the distance in kilometers between any two points on Earth, given their latitudes and longitudes. Here's the template:
#include <stdio.h> #include <math.h> // for M_PI and trig functions double dmsToRadians(double dms[3]) { /* * converts the values in the 3-element array `dms` (degrees, * minutes, and seconds) to a single double value in radians and * returns it * * pseudocode: * convert dms[] into a single (fractional) degree value * convert the degree value to radians and return that value */ } void polarToCartesian(double latitude[3], double longitude[3], double position[3]) { /* * converts `latitude` and `longitude` (both are 3-element -- * degrees, minutes, and seconds -- arrays) to `position`: a * 3-element double array in Cartesian (x, y, and z) coordinates * on the unit sphere. * * pseudocode: * convert latitude to a polar angle `theta` using * dmsToRadians() * convert longitude to an azimuthal angle `phi` using * dmsToRadians() * convert `theta` and `phi` to the x, y, and z components of * `position` */ } double arcLength(double latitude0[3], double longitude0[3], double latitude1[3], double longitude1[3]) { /* * computes the length (in radians) of an arc ("geodesic") on the * unit sphere between points (longitude0, latitude0) and * (longitude1, latitude1) * * pseudocode: * convert `latitude0` and `longitude0` to `position0` * using polarToCartesian() * convert `latitude1` and `longitude1` to `position1` * using polarToCartesian() * compute the cosine of the arc using the formula below * use the acos() (arc cosine) math function to convert the * cosine back to an angle and return it */ } double crowFly(double latitude0[3], double longitude0[3], double latitude1[3], double longitude1[3]) { /* * computes and returns the distance in km from (latitude0, * longitude0) to (latitude1, longitude1) on the Earth's surface * * pseudocode: * compute the arc length from (latitude0, longitude0) to * (latitude1, longitude1) using arcLength() * multiply the arc length by the radius of the Earth (6378 km) * and return that value */ } int main(void) { double latitude0[3], longitude0[3]; double latitude1[3], longitude1[3]; printf(" from latitude (d m s): "); scanf("%lf %lf %lf", &latitude0[0], &latitude0[1], &latitude0[2]); printf("from longitude (d m s): "); scanf("%lf %lf %lf", &longitude0[0], &longitude0[1], &longitude0[2]); printf(" to latitude (d m s): "); scanf("%lf %lf %lf", &latitude1[0], &latitude1[1], &latitude1[2]); printf(" to longitude (d m s): "); scanf("%lf %lf %lf", &longitude1[0], &longitude1[1], &longitude1[2]); printf(" distance: %.1f km\n", crowFly(latitude0, longitude0, latitude1, longitude1)); return 0; }
The code is available as
http://www.tricity.wsu.edu/~bobl/cpts121/lab05_functions/crow_fly_tplt.c
The main() function is provided. You do not need to change it. There are four other functions you need to implement, as indicated in the comments. Some additional notes:
This function takes a 3-element array containing an angle in degrees, (arc) minutes, and (arc) seconds and converts it to radians, which it returns. Remember that there are 60 seconds in a minute and 60 minutes in a degree and that there are 180 degrees in pi radians.
This function takes a latitude[] and a longitude[], both degree-minute-second 3-arrays, and converts them to radians theta and phi, respectively. These then create the x, y, and z components (in that order) of the position[] array, using these formulae:
x = cosθ cosφy = cosθ sinφz = sinθ
These are all 3D coordinates on a unit sphere (a sphere of radius one).
This function computes the length of an arc on the unit sphere in radians. Given positions p and q (position0 and position1 in the pseudocode), the formula for the arc length is
θ = cos − 1(pxqx + pyqy + pzqz)
This function returns the distance between two points (given their longitudes and latitudes) on the Earth's surface. (This is a very simple function.)
Here's a typical run for the distance between Richland and Pullman:
$ crow_fly from latitude (d m s): 46 16 47 from longitude (d m s): 119 16 53 to latitude (d m s): 46 44 0 to longitude (d m s): 117 10 0 distance: 169.7 km