CFrame:ToObjectSpace is working wrong

According to the wiki, CFrame*CFrame:ToObjectSpace(CFrame2) == CFrame2 and CFrame:ToObjectSpace(CFrame2) == CFrame:Inverse()*CFrame2 , and to me it works great…most of the cases. Now, I tried this with 2 normal parts of the workspace (I just put a Model in the workspace and put 2 parts there with a random position) and the re
sult is true. You can try this youself out:

local Model = workspace.TestModel

local CFrame1 = Model.Part1.CFrame
local CFrame2 = Model.Part2.CFrame

print(CFrame1*CFrame1:ToObjectSpace(CFrame2)==CFrame2)

But, when I try this out with some parts of my NPC, it says me false. I don’t understand why. And, if this isn’t confusing enough: If I try the other method, CFrame:Inverse()*CFrame2, it says me true! But, both methods should give me the same result, why is this here different? I mean, both result looks really the same, if not some small number changes:

-64.7682877, 101.081512, 54.2975464, -8.75882193e-08, -5.30979316e-10, 1, -1.00049725e-10, 1, 5.30979316e-10, -1, -1.00049698e-10, -8.75882193e-08 --CFrame:ToObjectSpace(CFrame2) Result
 
-64.7682877, 101.081512, 54.2975464, -8.75882193e-08, -5.30979316e-10, 1, -1.00049725e-10, 1, 5.30979316e-10, -1, -1.00049698e-10, -8.75882193e-08 --CFrame:Inverse()*CFrame2 Result

This shouldn’t affect my code heavly, but I am wondering what is the true result? The result of the ToObjectSpace or the result of the alternative way? This is more a question as a problem

You’re certainly encountering floating point issues, you could eventually try the following :

local Model = workspace.TestModel

local CFrame1 = Model.Part1.CFrame
local CFrame2 = Model.Part2.CFrame

print(CFrame1*CFrame1:ToObjectSpace(CFrame2):Dot(CFrame2.LookVector) <= 1e-5)
1 Like

I am just wondering why the results are different, because both functions should be the same, or not? If they are the same, then it dosen‘t make sense to get different results.

Could you explain what this code snippet does?

This is a problem of floating point numbers, because all the arithmetic that is done is not exact, but approximate. Most probably, two numbers will never be the same (I say probably, because they can be equal by pure coincidence or by a software optimization). Therefore, you should always assume that two floating point numbers will never be the same.

What can be done is to verify their approximate equality, by taking a minimum error. If the difference of two numbers is less than the error, then we can say that both numbers are equal.

Here is a more detailed explanation.

Therefore you should assume that both methods are the same and always use approximate equality if you want to compare two CFrames or any object that handles floating point numbers.

2 Likes

Using == to compare numbers after arithmetic could cause it to sometimes return false even though the equations should be equal due to floating point error.

print(0.1 + 0.1 == 0.2) -- will return true
print(0.1 + 0.1 + 0.1 == 0.3) -- will return false, when it should be true

The best way to get around is to specify a tolerance range that’s considered to be a “match”. If the values are “equal”, then their difference should be close to 0.

print(math.abs(0.1 + 0.1 - 0.2) <= 1e-5) -- will return true
print(math.abs(0.1 + 0.1 + 0.1 - 0.3) <= 1e-5) -- will return true

This is what @Elia171 is setting up, although it’s the CFrame vs CFrame case, rather than the simple two numbers case.

Although, I think there’s a slight code error with that line since it’s doing CFrame:Dot(Vector3)

print((CFrame1*CFrame1:ToObjectSpace(CFrame2)).UpVector:Dot(CFrame2.LookVector) <= 1e-5)

Should yield true.

3 Likes