Vector3:FuzzyEq (and its alias :isClose) return incorrect results

  • Detailed description of bug;
    Using Vector3:FuzzyEq and Vector3:IsClose returns incorrect results.

  • Where the bug happens (be specific);
    Example case:
    Vector3.new(1,2,1):isClose(Vector3.new(1,1,1), .5)

Expected result: false (since (v1 - v2).Magnitude = 1, which is greater than .5)
Actual result: true

  • When it started happening;
    As far as I know, it was recently

  • Steps to reproduce the issue (be minimal, specific, consistent!);
    type print(Vector3.new(1,2,1):isClose(Vector3.new(1,1,1), .5)) into the console.

Edit: Thanks to @evaera for the insightful response!
I’ll leave this bug up as a documentation issue, since referring to :FuzzyEq in the documentation as " epsilon radius" is still incredibly misleading nonetheless.

4 Likes

FuzzyEq is not a magnitude check. It actually works like this:

Two vectors A and B are considered close if each pair of axes individually from A and B pass this check:

a == b or math.abs(a - b) <= (math.abs(a) + 1) * epsilon

E.g., pure lua impl:

function fuzzyEq(a, b, epsilon)
	return a == b or math.abs(a - b) <= (math.abs(a) + 1) * epsilon
end

function fuzzyEqVec(v1, v2, epsilon)
	for _, axis in ipairs({"X", "Y", "Z"}) do
		if not fuzzyEq(v1[axis], v2[axis], epsilon) then
			return false
		end
	end
	
	return true
end

print(fuzzyEqVec(Vector3.new(1, 2, 1), Vector3.new(1, 1, 1), .5)) --> true

Why does it work like this? To let the allowed error skew get larger as floating point numbers lose precision.

16 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.