Floating point errors when comparing 2 CFrames

  1. What do you want to achieve?
    I want to compare 2 CFrames without any floating point errors
  2. What is the issue?
    When I compare 2 CFrames at the exact same position the 2 CFrames have a slightly different position.
    devforum1 devforum2
  3. What solutions have you tried so far?
    I have tried no solutions because I can’t find an article on this.

I am comparing the CFrames like this:

if CFrame1 == CFrame2 then
--Code
end

I’ve dealt with this issue when using a repeat loop to enlarge a Gui instead of tweening it. It’s a problem of floating-point arithmetic. I think the best way to deal with this is to round the CFrames. Since it’s such a small difference from the actual numbers, the rounded numbers should be identical.

1 Like

Thanks, It works now. I implemented my round function like this:

local function roundCFrame(cframe)
	return CFrame.new(math.floor(cframe.X), math.floor(cframe.Y), math.floor(cframe.Z))
end
1 Like

This seems like a terrible idea:

In the case you use math.floor and have a CFrame that has a x position of 2 and is compared to a CFrame with a x position of 1.99…, they wouldn’t match.

Similarly, using math.round, having a CFrame with x equal to 2.5 compared to a CFrame of x equal to 2.49… would also return a false.

Not to mention the solution only works with the position of the CFrames, not the rotation, and has an error distance of an entire stud. A better way to compare the positions is to do the following:

local epsilon = 0.0001

local function compareCFramePosition(a: CFrame, b: CFrame): boolean
    if (a.Position - b.Position).Magnitude < epsilon then
        return true
    end

    return false
end

(a.Position - b.Position) gets a vector from position B to position A. We can use this to get the difference like 0.00001 = 2.5 - 2.49999

Because we have a vector3, we use Roblox in-built magnitude method to get the length of the vector3.

Similarly, if you want to check the rotation of CFrames I suggest doing the same thing but instead of Position use the LookVector of the CFrame like so:

local function compareCFrameRotation(a: CFrame, b: CFrame): boolean
    if (a.LookVector - b.LookVector).Magnitude < epsilon then
        return true
    end

    return false
end

I bet there’s a more official way of doing this like comparing the Rotation property, but this is a pretty inexpensive and accurate method already.

2 Likes