Cardinal direction algorithm in Java

后端 未结 5 1704
故里飘歌
故里飘歌 2021-02-04 05:22

This weekend I spend a few minutes thrashing together an algorithm that would take in a heading (in degrees) and return a String for the cardinal direction (I\'m using it in an

相关标签:
5条回答
  • 2021-02-04 05:30

    The previous examples are not accurate, here is a more accurate solution in JavaScript.

    function getCardinalDirection(input) {
        var directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"];
        var index = Math.floor( ((input-22.5)%360) / 45 );
        return directions[index+1];
    }
    
    0 讨论(0)
  • 2021-02-04 05:31

    That's fine in most cases, though to make it optimized and (IMO) cleaner, what you could do is find a function to relate the input heading to one used in the map.

    For example: (I'm pretty sure this is right, but you'll want to check it)

    45* (int)Math.round((  ((double)x % 360) / 45))
    

    What this does is first x % 360 makes sure the heading is within a valid range. then

    45 * round(.../45)
    

    finds the closest multiple of 45.

    Now change your map to be

      HashMap<Integer, String> map = new HashMap<Integer, String>()
      map.put(0, "North")
      map.put(45, "Northeast")
      etc...
    

    So, now your algorithm becomes a fast mathemtical calculation rather than iterating through the map. Furthermore, you don't need as Hashtable here since it provides constructs for concurrency (if I remember correctly) and in your case it would actually cause a performance decrease.

    Once again, the performance hit may be completely negligible for your needs.

    Edit for Thilo's and shinjin's suggestions:

    Instead of multiplying by 45, just keep the rest of the equation, which gives you values for 0-7, and make an array of your strings.

    String directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}
    return directions[ (int)Math.round((  ((double)x % 360) / 45)) % 8 ]
    

    and you've got your problem solved in two lines.

    One note: Modulus won't work correctly for negative numbers. If our input heading is negative, you'll need to make it positive first.

    0 讨论(0)
  • 2021-02-04 05:35

    Most of the answers here are off by 22.5 degrees for their 45 degree intervals, and map e.g. 0-45 as N, rather than [337.5-360],[0-22.5] to N. You need to offset before doing the math to correct for this.

    Here's a solution that uses 22.5 degree intervals, such as you might see for wind directions:

      private String formatBearing(double bearing) {
        if (bearing < 0 && bearing > -180) {
          // Normalize to [0,360]
          bearing = 360.0 + bearing;
        }
        if (bearing > 360 || bearing < -180) {
          return "Unknown";
        }
    
        String directions[] = {
          "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
          "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",
          "N"};
        String cardinal = directions[(int) Math.floor(((bearing + 11.25) % 360) / 22.5)];
        return cardinal + " (" + formatBearing.format(bearing) + " deg)";
      }
    
    0 讨论(0)
  • 2021-02-04 05:35

    You could maybe add 15 degrees up front to avoid North_1 and North_2.

    0 讨论(0)
  • 2021-02-04 05:41

    in java:

    String _directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
    
    public String getHeading(int hea) {
      return _directions[(int)Math.floor((hea % 360) / 45)];
    }
    

    In "java" case u must need to create a Class.

    in javascript:

    var _directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
    
    function getDirection (hea) {
      return _directions[Math.floor((hea % 360) / 45)];
    };
    
    0 讨论(0)
提交回复
热议问题