Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Vector2.SignedAngle backwards?

Discussion in 'Scripting' started by andyz, Sep 4, 2019.

  1. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,236
    I have a hard time understanding why Vector2.SignedAngle(new Vector2(0, 1f), new Vector2(1, 0f)) returns -90;
    This seems to assume +y is down but in the x/y plane of Unity y is up. So why is this?

    Even worse if you write it as Vector2.SignedAngle(Vector2.up, Vector2.right) - how does that make sense?
     
    Last edited: Sep 4, 2019
  2. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,236
    No comment on this?
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,274
    I've pointed it out before.

    The "solution" is to use Vector3.SignedAngle, and provide the correct "up" axis for your vectors (ie. Vector3.back).
     
    ledshok likes this.
  4. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,236
    OK, good. But I would say the solution is just -Vector2.SignedAngle, but why unity?!
     
  5. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    Because this way positive rotation angle becomes counterclockwise. It should not be a surprise to unity users because rotating object using inspector gives the same result. Positive angle is counterclockwise for any axis.
     
  6. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,236
    It is not a surprise for 3d but for 2d x/y maths it is, however given sprites and RectTransforms do not even pretend to be 2d for rotation perhaps it is to be expected
     
  7. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    They just ignore Z coordinate and use canvas hierarchy for rendering order. RectTrasform is based on Transform and they using same matrices and coordinate system.
     
  8. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,274
    It is surprising to Unity users that read the docs for signed angle that very specificly states that it uses a clockwise angle:

    I've delivered a bug report, but I'm pretty sure that it's the docs that are wrong here. Also note that it states that the angle is acute, and between -180 and 180, which is also just plain wrong.

    Both implementations are valid, but the docs shouldn't state the opposite of what the implementation is! It should also probably know what the maths terms it uses mean!

    If starting from scratch, I would've implemented this as a clockwise angle - it makes very little sense to look at a clock sprite from the front, and say that the angle from 12 o' clock to 3 o' clock is -90. I don't think it's worth the breakage that would ensue if the function got "fixed", though, so the docs should just be fixed instead.
     
    andyz and palex-nx like this.
  9. Double-V

    Double-V

    Joined:
    Aug 13, 2016
    Posts:
    21
    The docs still say it's clockwise. I ran into this thread exactly because I read them first and then discovered that it's not doing the expected thing and went searching for answers.
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,854
    Well, it's true that the docs are wrong. However the normal mathematical definition is counter clockwise. All trig functions are based on counter clockwise rotation and 0° are usually the positive x axis. In the case of SignedAngle we specify the reference ourselfs. So doing "Vector2.SignedAngle(Vector2.up, Vector2.right)" it should return -90 since that's a clockwise rotation.

    You get the same behaviour from Atan2 which can be used to get the angle between the positive x axis and your given vector. So
    Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg
    is comparable to
    SignedAngle(Vector2.right, v);
    for a given vector v.

    See Rotation (wikipedia) for more information. To quote:

    See also Clockwise (wikipedia). or Euler's formula(wikipedia). Literally everything related to rotations in math is based on a counter clockwise rotation.
     
  11. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,236
    This is an interesting point and some libraries use 0 as right but I feel like that is more the hard-maths community and most developers use a compass-style angle system. But I wonder on the stats...
     
  12. Wambosa

    Wambosa

    Joined:
    Jun 2, 2013
    Posts:
    12
    This method burned me + lost me two dev days. I spent a long time troubleshooting around it thinking that something was off with my algorithm, well it was this function in there.

    I swapped to using a
    Code (CSharp):
    1. Quaternion.Inverse(transform.rotation) * vec2Direction
    and it was more clear to me how to use that output.

    There is a high probability that I was using the wrong method in the first place.