; List of abbreviated compass point labels make "compass_points [ N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE S SbW S-SW SWbS SW SWbW W-SW WbS W WbN W-NW NWbW NW NWbN N-NW NbW ] ; List of angles to test make "test_angles [ 0.00 16.87 16.88 33.75 50.62 50.63 67.50 84.37 84.38 101.25 118.12 118.13 135.00 151.87 151.88 168.75 185.62 185.63 202.50 219.37 219.38 236.25 253.12 253.13 270.00 286.87 286.88 303.75 320.62 320.63 337.50 354.37 354.38 ] ; make comparisons case-sensitive make "caseignoredp "false ; String utilities: search and replace to replace_in :src :from :to output map [ ifelse equalp ? :from [:to] [?] ] :src end ; pad with spaces to pad :string :length output cascade [lessp :length count ?] [word ? "\ ] :string end ; capitalize first letter to capitalize :string output word (uppercase first :string) butfirst :string end ; convert compass point abbreviation to full text of label to expand_point :abbr foreach [[N north] [E east] [S south] [W west] [b \ by\ ]] [ make "abbr replace_in :abbr (first ?) (last ?) ] output capitalize :abbr end ; modulus function that returns 1..N instead of 0..N-1 to adjusted_modulo :n :d output sum 1 modulo (difference :n 1) :d end ; convert a compass angle from degrees into a box index (1..32) to compass_point :degrees make "degrees modulo :degrees 360 output adjusted_modulo (sum 1 int quotient (sum :degrees 5.625) 11.25) 32 end ; Now output the table of test data print (sentence (pad "Degrees 7) "\| (pad "Closest\ Point 18) "\| "Index ) foreach :test_angles [ local "index make "index compass_point ? local "abbr make "abbr item :index :compass_points local "label make "label expand_point :abbr print (sentence (form ? 7 2) "\| (pad :label 18) "\| (form :index 2 0) ) ] ; and exit bye