Rosetta Code

Box the compass

Map degree headings to the correct 32-point compass names for the Rosetta Code sample bearings.

Medium View source
Source rosettacode/popular/box_the_compass.vibe
# title: Box the compass
# source: https://rosettacode.org/wiki/Box_the_compass
# category: Rosetta Code
# difficulty: Medium
# summary: Map degree headings to the correct 32-point compass names for the Rosetta Code sample bearings.
# tags: popular, navigation, lookup, geometry
# vibe: 0.2

def compass_points
  [
    "North",
    "North by east",
    "North-northeast",
    "Northeast by north",
    "Northeast",
    "Northeast by east",
    "East-northeast",
    "East by north",
    "East",
    "East by south",
    "East-southeast",
    "Southeast by east",
    "Southeast",
    "Southeast by south",
    "South-southeast",
    "South by east",
    "South",
    "South by west",
    "South-southwest",
    "Southwest by south",
    "Southwest",
    "Southwest by west",
    "West-southwest",
    "West by south",
    "West",
    "West by north",
    "West-northwest",
    "Northwest by west",
    "Northwest",
    "Northwest by north",
    "North-northwest",
    "North by west"
  ]
end

def compass_boundaries
  [
    5.625,
    16.875,
    28.125,
    39.375,
    50.625,
    61.875,
    73.125,
    84.375,
    95.625,
    106.875,
    118.125,
    129.375,
    140.625,
    151.875,
    163.125,
    174.375,
    185.625,
    196.875,
    208.125,
    219.375,
    230.625,
    241.875,
    253.125,
    264.375,
    275.625,
    286.875,
    298.125,
    309.375,
    320.625,
    331.875,
    343.125,
    354.375
  ]
end

def normalize_heading(degrees)
  while degrees < 0.0
    degrees = degrees + 360.0
  end
  while degrees >= 360.0
    degrees = degrees - 360.0
  end
  degrees
end

def heading_to_point(degrees)
  heading = normalize_heading(degrees)
  boundaries = compass_boundaries
  points = compass_points
  index = 0
  while index < boundaries.size
    if heading < boundaries[index]
      return points[index]
    end
    index = index + 1
  end
  points[0]
end

def sample_headings
  [
    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
  ]
end

def build_rows
  rows = []
  headings = sample_headings
  index = 0
  while index < headings.size
    rows = rows + [{
      index: (index % 32) + 1,
      point: heading_to_point(headings[index]),
      degrees: headings[index]
    }]
    index = index + 1
  end
  rows
end

def run
  build_rows
end
Output
Press run to execute run from this example.
rosetta-code popular navigation lookup geometry browser-runner