# C++: Box the Compass

Avast me hearties!

There be many a land lubber that knows naught of the pirate ways and gives direction by degree! They know not how to box the compass!

1. Create a function that takes a heading in degrees and returns the correct 32-point compass heading.
2. Use the function to print and display a table of Index, Compass point, and Degree; rather like the corresponding columns from, the first table of the wikipedia article, but use only the following 33 headings as input:
`[0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]`. (They should give the same order of points but are spread throughout the ranges of acceptance).
Notes;
• The headings and indices can be calculated from this pseudocode:
```for i in 0..32 inclusive:
heading = i * 11.25
case i %3:
if 1: heading += 5.62; break
if 2: heading -= 5.62; break
end
index = ( i mod 32) + 1```
• The column of indices can be thought of as an enumeration of the thirty two cardinal points (see talk page).

```#include <string>
#include <boost/array.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <math.h>
using std::string;
using namespace boost::assign;

int get_Index(float angle)
{
return static_cast<int>(floor(angle / 11.25 +0.5 )) % 32 + 1;
}

string get_Abbr_From_Index(int i)
{
static boost::array<std::string, 32> points(list_of
("N")("NbE")("NNE")("NEbN")("NE")("NEbE")("ENE")("EbN")
("E")("EbS")("ESE")("SEbE")("SE")("SEbS")("SSE")("SbE")
("S")("SbW")("SSW")("SWbS")("SW")("SWbW")("WSW")("WbS")
("W")("WbN")("WNW")("NWbW")("NW")("NWbN")("NNW")("NbW"));
return points[i-1];
}

string Build_Name_From_Abbreviation(string a)
{
string retval;
for (int i = 0; i < a.size(); ++i){
if ((1 == i) && (a[i] != 'b') && (a.size() == 3)) retval += "-";
switch (a[i]){
case 'N' : retval += "north"; break;
case 'S' : retval += "south"; break;
case 'E' : retval += "east";  break;
case 'W' : retval += "west";  break;
case 'b' : retval += " by ";  break;
}
}
retval[0] = toupper(retval[0]);
return retval;
}

int main()
{
(0.0)(16.87)(16.88)(33.75)(50.62)(50.63)(67.5)(84.37)(84.38)(101.25)
(118.12)(118.13)(135.0)(151.87)(151.88)(168.75)(185.62)(185.63)(202.5)
(219.37)(219.38)(236.25)(253.12)(253.13)(270.0)(286.87)(286.88)(303.75)
(320.62)(320.63)(337.5)(354.37)(354.38));
int i;
boost::format f("%1\$4d %2\$-20s %3\$_7.2f");

{
i = get_Index(a);
std::cout << f % i %  Build_Name_From_Abbreviation(get_Abbr_From_Index(i)) % a << std::endl;
}
return 0;
}
```

### Output:

```   1 North                   0.00
2 North by east          16.87
3 North-northeast        16.88
4 Northeast by north     33.75
5 Northeast              50.62
6 Northeast by east      50.63
7 East-northeast         67.50
8 East by north          84.37
9 East                   84.38
10 East by south         101.25
11 East-southeast        118.12
12 Southeast by east     118.13
13 Southeast             135.00
14 Southeast by south    151.87
15 South-southeast       151.88
16 South by east         168.75
17 South                 185.62
18 South by west         185.63
19 South-southwest       202.50
20 Southwest by south    219.37
21 Southwest             219.38
22 Southwest by west     236.25
23 West-southwest        253.12
24 West by south         253.13
25 West                  270.00
26 West by north         286.87
27 West-northwest        286.88
28 Northwest by west     303.75
29 Northwest             320.62
30 Northwest by north    320.63
31 North-northwest       337.50
32 North by west         354.37
1 North                 354.38```

SOURCE

Content is available under GNU Free Documentation License 1.2.