Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-5240

Bukkit's Vector#angle(Vector) is broken

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • None
    • None
    • git-Spigot-cbcc8e8-06efc9e (MC: 1.14.4) (Implementing API version 1.14.4-R0.1-SNAPSHOT)
    • Yes

      It appears that for certain vectors, Vector#angle(Vector) returns NaN. This doesn't make sense since there is always an angle between two non-zero vectors which should always be 0 to 180 degrees inclusive.
       
      This is the current implementation in Bukkit:

      public float angle(@NotNull final Vector other) {
          final double dot = this.dot(other) / (this.length() * other.length());
          return (float)Math.acos(dot);
      }
      

       
      Although this is correct mathematically, there is an issue that needs to be addressed. The value of "dot" should be within the domain [-1, 1]. For some vectors pointing extremely close towards the same direction, "dot" will lie slightly out of the domain due to floating point precision errors. If "dot" does not lie within that domain, then Math.acos(double) will return NaN.
       
      I suggest to wrap the dot computation inside of Math.min(double, double) and Math.max(double, double) to ensure that "dot" is within the domain [-1, 1].

      public float angle(@NotNull final Vector other) {
          double dot = Math.min(Math.max(this.dot(other) / (this.length() * other.length()), -1), 1);
          return (float)Math.acos(dot);
      }

            Unassigned Unassigned
            Islandscout Islandscout
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: