Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Unity alterning my Vector3/Positions :(

Discussion in 'Scripting' started by ccAdam, Mar 5, 2017.

  1. ccAdam

    ccAdam

    Joined:
    Jan 25, 2015
    Posts:
    24
    Unity, Why you do this?

    Can Anyone explain why Unity likes to change my Vector3 values that I calculated for my bounding-box corners.



    All the extremly small 0.0000005 decimals should according to my calculations be equal to 0. I am 100% sure of that as I've debugged it. But Why when I see the inspector, Unity has changed some of the values?
     
  2. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    5.057622e-07 = 0.0000005057622 which is probably as close as floating points can get to 0.0000005
     
    Kiwasi likes this.
  3. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    How were the values calculated? I've seen Transform-related vectors change like that sometimes, probably because Unity sometimes seems to convert between local and world space and small errors creep in. With these, they appear to be custom vectors of your own, so it all comes down to how you calculate them.

    And if your calculations are in the least bit complex, don't expect to be able to preserve analytic perfection. Floating point numbers have a finite amount of precision; beyond that, you're losing small amounts of information, and there's very little you can do about it. For example, calculating the distance between two arbitrary points will be really close to correct, but it's only in rare cases that it is 100% perfect.
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You are going to run into trouble so close to the limits of Unity's precision. I'd suggest reworking things so you never get that close.
     
  5. ccAdam

    ccAdam

    Joined:
    Jan 25, 2015
    Posts:
    24
    It's a simple calculation of rotated vector3 with Quaternion.Euler. I basically created my own Transform.RotateAround but for Vector3.
    Here is the function

    Code (CSharp):
    1.  public Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles) {
    2.    Vector3 dir = point - pivot; // get point direction relative to pivot
    3.    dir = Quaternion.Euler(angles) * dir; // rotate it
    4.    point = dir + pivot; // calculate rotated point
    5.    return point; // return it
    6. }
    Now I loop through every 4 vector3 in my square to rotate the whole square to the desired angle. The problem is this, if my initial vector3 positions are whole numbers, and I rotate them 90/180/270/360 degrees, shouldn't the resulting vector3 positions also be whole numbers
     
  6. booiljoung

    booiljoung

    Joined:
    May 12, 2013
    Posts:
    57
    Hi there,

    The real numbers of mathematics and computers are different.
    The real number of mathematics is unlimited.
    The computer float type has 32bits limit.
    For more information, see the IEEE-754 document.

    This is not a problem caused by Unity.
    This is caused by your computer (CPU, GPU, Memory).
    Any software gives these calculated results.

    On a computer, 1.1f / 1.1f should not be considered 1.f.
    When comparing, you should use Mathf.Approximately.

    Https://en.wikipedia.org/wiki/Single-precision_floating-point_format
    https://docs.unity3d.com/ScriptReference/Mathf.Approximately.html
     
    chelnok likes this.
  7. ccAdam

    ccAdam

    Joined:
    Jan 25, 2015
    Posts:
    24
    I'm not not comparing floats, they are only for positions but I'm thinking of rounding them to the 2 first decimal places for a more accurate result
     
    Last edited: Mar 6, 2017
  8. ccAdam

    ccAdam

    Joined:
    Jan 25, 2015
    Posts:
    24
    If so, how come my windows calcultor not return wierd decimals?
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It probably uses doubles. Which pushes the problem out another dozen places or so.
     
  10. Akfly

    Akfly

    Joined:
    Jan 31, 2017
    Posts:
    12
    I get this numbers sometimes when I copy and paste a GameObject (on position, rotation or scale). When it happens, I change the value to 1 and then to 0 again :p
     
  11. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    What every computer scientist should know about floating point.

    Whenever you start doing calculations with floating point numbers you're going to start seeing precision issues like this. If you want the results of your calculations to be 0 or 90 or whatever then round them or specifically set them if they're close.

    Code (csharp):
    1. if (Mathf.Approximately(result.x, 90.0f)) result.x = 90.0f;
    2. // etc.
     
  12. ccAdam

    ccAdam

    Joined:
    Jan 25, 2015
    Posts:
    24
    I chose to round them to second decimal place.
     
  13. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    If you're still curious about precisely where the small error is coming from, Quaternion.Euler(angles) is quite a bit more complicated than you might be expecting. The function publicly works with degrees, but under the hood, it almost undoubtedly converts those degrees to radians for use with standard trigonometric functions, and it is impossible to exactly represent 90/180/270 degrees in radians on a computer, no matter how many digits you have room for. You can blame this on pi being irrational.

    If I were writing this function and absolutely required numeric perfection, I'd consider geting rid of the Quaternion.Euler() call entirely, and computing the rotated dir manually. If all your rotations are in 90 degree increments, all changes to dir are going to end up just being a swapping and changing of sign of the x/y/z components, no fancy math needed. Though it could get messy with all the conditionals unless you found a clever way to structure it, so the rounding which you opted for could indeed be seen as an acceptable engineering choice; easy to write; easy to understand later on.
     
    Last edited: Mar 6, 2017
  14. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Or just wear the error. It will take a long time before it adds up to something noticeable.
     
    AndyGainey likes this.