Answers for "Vector2.Dot not returning 0"
http://answers.unity.com/questions/1214189/vector2dot-not-returning-0.html
The latest answers for the question "Vector2.Dot not returning 0"Answer by Eno-Khaon
http://answers.unity.com/answers/1214204/view.html
Welcome to the wonderful world of floating point inaccuracy!
<b>Zero</b> happens to be an <b>extremely</b> unlikely number to see in a floating point variable. This is because the closer the number gets to <b>0</b>, the closer it <i>can</i> be to <b>0</b>.
<i>What does that mean?</i>
Floating point numbers are stored in a form similar to scientific notation. This combines <sub><sup>(something like)</sup></sub> an integer with a power-of-10 exponent. To give an example of this:
Let's use <b>7823846</b> as our base value. Then, let's turn that into a very large and a very small number, such as <b>7.823846e10</b> and <b>7.823846e-7</b>, or <b>78238460000</b> and <b>0.0000007823846</b> respectively.
If you increased the base integer value by 1 at this point, you would see a change of <b>1000</b> or <b>0.0000000000001</b> respectively. <b>[There is a limit on how long the base value can be][1]</b>, as well as how far the decimal point can be placed along the number in either direction.
In short, what this means in this case is that while the number <b>can</b> reach <b>0</b>, it is extremely unlikely when paired with slight inaccuracy of floating point numbers. For instance, if you've ever seen something like <b>0.999999999</b> instead of <b>1</b>, it's basically indistinguishable in truth, but the number appears to be drastically different.
Well, this is the same sort of dilemma. You have near-infinite granularity available as you get closer to <b>0</b> and it becomes less and less likely that the floating point value will accurately calculate a result of <b>0</b>.
This is why Unity has a simple, convenient <b>[workaround][2]</b> to accommodate this accuracy issue for minute differences between numbers.
float differenceDot = Vector2.Dot (preyWorldDir, huntToPreyDir);
if(Mathf.Approximately(differenceDot, 0.0f))
print("= 0");
else if(differenceDot > 0)
print("> 0");
else// if(differenceDot < 0)
print("< 0");
[1]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
[2]: https://docs.unity3d.com/ScriptReference/Mathf.Approximately.htmlSun, 10 Jul 2016 17:20:11 GMTEno-KhaonAnswer by Bunny83
http://answers.unity.com/answers/1214197/view.html
It's almost impossible that Dot returns 0 since you work with floating point values. It only returns 0 when it's exactly 90°. If there is a small difference (0.000001) it won't return 0.
If you want to know when it's "about" 90° you might want to do this:
float d = Vector2.Dot (preyWorldDir, huntToPreyDir);
if (d < -0.9f)
print ("behind");//Hunter is behind prey
else if (d > 0.9)
print ("in front");//Hunter is in front of prey
else
print ("perpendicular");//Hunter is perpendicular of prey
If you want to split the area at the 45° angle into 4 quadrants you might want to use 0.7071 (cos(45°)). That way the "front" area has a size of 90° (+-45°) as well as the "back" area. Of course both sides also have that size.
if (d < -0.7071f)
print ("behind");//Hunter is behind prey
else if (d > 0.7071)
print ("in front");//Hunter is in front of prey
else
print ("perpendicular");//Hunter is perpendicular of prey
***edit***
I have missed that little detail about your code. As said in the comment below you haven't normalized your "huntToPreyDir" vector. If you don't work with normalized vectors the result of the dot product has a different meaning.
The dot product simply does this:
float Dot(Vector2 a, Vector2 b)
{
return a.x * b.x + a.y * b.y;
}
The nice property about the dot product is this relation:
Dot(a, b) = |a| * |b| * cos(angle);
or written in Unity C#_
a.magnitude * b.magnitude * Mathf.Cos(angle);
where angle is the angle between the two vectors.
If both vectors are normalized that means the length / magnitude of each vector is "1f" so the dot product simply returns the cos(angle) between the two vectors. This is what you want most the time.
If only one vector is normalized and the other isn't you actually project the length of the unnormalized vector onto the other vector.
If both vectors are not normalized the result of the dot product would be the area of the parallelogram with the two side length "a" and "b".
So you should normalize your vector like this:
Vector2 huntToPreyDir = (transform.position - prey.transform.position).normalized;Sun, 10 Jul 2016 17:04:26 GMTBunny83