x


Good old trig and NaN

Got a function that uses a lot of trig

private static Vector3 AdjustGravityToNormal(float velocity, Vector3 groundNormal)
{
    if (groundNormal == Vector3.up)
        return Vector3.zero;

    var angle = Mathf.Acos(groundNormal.y);

    var magnitude = velocity * Mathf.Sin(angle);

    var vMagnitude = magnitude * Mathf.Sin(angle);
    var hMagnitude = -magnitude * Mathf.Cos(angle);

    var horizontal = new Vector2(groundNormal.x, groundNormal.z).normalized * hMagnitude;

    return new Vector3(horizontal.x, vMagnitude, horizontal.y);
}

It used to quite regularly return Vector3(NaN, NaN, NaN) when on a flat (Vector3 == Vector3.Up) even though it shouldn't.

Input position is { NaN, NaN, NaN }.

So I added the if (groundNormal == Vector3.up) return Vector3.zero; part and it got rid of most of the errors. But I still get the very rare occasional one and I'd like to get rid of it.

Any ideas?

Bonus Question which will probably solve original question so I'll leave it in same answer. Haven't really done vectors/trig in maybe 6 years so I'm a bit rusty. But does anyone know how to rewrite my function a lot cleaner? I'm pretty sure there are ways to do it using cross products etc. Pretty much the function is manually calculating the force in the x,y,z direction on a slope for gravity.

more ▼

asked Mar 03 '11 at 10:40 PM

tertle gravatar image

tertle
1.1k 15 18 33

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

Think I've solved this by adding

groundNormal = Vector3.ClampMagnitude(groundNormal, 1);

Up the top. Guess normal was returning a number marginally over 1 due to floating point error or something.

more ▼

answered Mar 04 '11 at 12:02 AM

tertle gravatar image

tertle
1.1k 15 18 33

Regarding the numerical errors, you should probably clamp the input to Acos() to the range [-1, 1] rather than clamping the vector's magnitude. The latter might work in this case, but the former is the generally accepted method of ensuring that the input to Acos() is valid.

Mar 04 '11 at 07:10 AM Jesse Anders
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x984
x461
x292
x195

asked: Mar 03 '11 at 10:40 PM

Seen: 1826 times

Last Updated: Mar 03 '11 at 10:40 PM