Vector3 == comparison efficiency and float precision

what is the error rate comparing Vector3’s to be == ?

I seem to have about 20% of my objects missing when I compare to see if the objects are there, with :
if (Vector3(X, Y, Z) == Vector3 (X, Y, Z)){ do something;}

I would prefer to compare them using integers/mathf.round, although there are many 1000ds compare, so I am concerned about speed. What is the the most efficient way to check many Vector3 == precisely?

here’s a pic: if no tiles == expected terrain, make tile @ expected terrain… it’s missing a line of tiles until spaceship position is updated.

[7607-missing+tiles.jpg|7607]

Vector3 comparison must be based on distance: if the distance between two Vector3 is less than some predefined value, they are considered equal. This is exactly what Unity does when you compare two Vector3 (Vector3 == operator as implemented in Unity):

public static bool operator ==(Vector3 lhs, Vector3 rhs)
{
	return Vector3.SqrMagnitude(lhs - rhs) < 9.99999944E-11f;
}

This function is called by Unity in the compiled code whenever you compare two Vector3 values, thus doing it yourself will not cause any loss in performance - for instance:

public bool V3Equal(Vector3 a, Vector3 b){
    return Vector3.SqrMagnitude(a - b) < 0.0001;
}

This limit is equal to 0.1mm, very small but still one million times greater than the builtin limit.

My fault! We’re comparing squared magnitude, thus this limit equals 0.01 m, or 1 cm as noticed by @higekun in the comments (for 0.1 mm the value should be 0.00000001). For other limits, follow @Bunny83’s suggestion (also posted in the comments).

In practice, you should replace the Vector3 equality operators by a call to this function, like this:

if (posA == posB){ // < --- replace this...
    ...

if (V3Equal(posA, posB)){ // < -- with this
    ...

As the vector components are floats comparison for equality is kind of tricky. I’d use a helper function to test with some given precision. Something like:

public static bool AlmostEqual(Vector3 v1, Vector3 v2, float precision)
{
    bool equal = true;
		
	if (Mathf.Abs (v1.x - v2.x) > precision) equal = false;
	if (Mathf.Abs (v1.y - v2.y) > precision) equal = false;
	if (Mathf.Abs (v1.z - v2.z) > precision) equal = false;
		
    return equal;
}

If that’s too slow you can consider some optimization afterwards.

You can use the Mathf.Approximately function to test floating point values for “equality”. You would have to test each vector component. Another method would be to subtract the two vectors and use Vector3.sqrMagnitude to test the length. That’s potentially less efficient though.

The best way to check the performance is to write the code and check the performance.

Floats are approximations, and all kinds of things can affect their actual value (release mode, platform, how they were derived)… so even if == sometimes works, it’s generally not a good idea.

For vector comparisons, you can use something like this:

float d = Vector3.SqrMagnitude(a - b);
if (d > EPSILON) {
	// something amazing
}

SqrMagnitude is faster than Magnitude since no square root is needed, but there are still a few multiplies involved.

If this is too slow, consider why you have so many comparisons to begin with. For example, it looks like you’re using a grid structure: can you check for objects only in the local neighborhood by using grid coordinates (relative integers)? Can you use some other spatial data structure?

The Unity implementation of Vector3 == already accounts for “approximately equal”. The documentaiton states:

This will also return true for vectors that are really close to being equal.

Further, there appears to be an undocumented public member:

public const float kEpsilon = 1e-005f;

One presumes that this constant is used for the “close enough” comparison.

Vector2 also have this feature.