How to multiply CFrames?

I know that multiplying CFrames make them adding but how can we multiply them???
CFrames are already hard to understand but when we know that multiplying is adding and LookAt is the angle but it’s using a position to look, it gets very hard.

1 Like

CFrame * CFrame
As in like

Part1.CFrame * Part2.CFrame

Like just treat them as numbers like 5*5

But it adds them (so why CFrame + CFrame doesn’t work?)

1 Like

Maybe read this article about CFrame Math Operations?

1 Like

To first understand why multiplying CFrames can come out to be “adding”, we need to break down CFrames a bit.
The first 3 parts of the CFrame dictate a position. For example, CFrame.new(0,0,0) will refer to the position at “0,0,0” in the place. However, there are 9 other components after, which refer to the rotation. Therefore, by multiplying the CFrames, you aren’t just multiplying the position components, but all the aspects. CFrames are set in a matrice, so it’s not as simple as 3 x 5. This multiplication of matrices could probably turn up to adding the positions.

For why you can’t add CFrames, I can’t be completely sure, but when you add matrices, you add them by their position in the matrice. For example, what’s in row 1, column 1 of a matrice would be added to the number with that same position of the other matrice, and this would repeat for each position in the matrices. As the other 9 components go towards rotation, when you add them, they probably won’t show a proper rotation aspect. For example, if you type in a part’s orientation (which is rotation) as “90,-180,0”, Studio will correct it to “90,180,0”. My guess would be that things like that could frequently occur when adding CFrames, so adding CFrames isn’t optimal. However, this is just my hypothesis on why you can’t add CFrames, but regardless, Roblox does not let doing CFrame + CFrame, as far as I’m aware.

If you wanted to multiply the position of the CFrame, you can simply just multiply each position coordinate with the number you want to multiply them by, such as CFrame.new(1 x 3, 4 x 4, 2 x 4).

Sorry if this is confusing, or my guess on why you can’t add them is inaccurate, but all in all, to multiply the position aspects of a CFrame, you can multiply them by the number you wanted to multiply with, like CFrame.new(1 x 3, 4 x 4, 2 x 4).

5 Likes

It doesn’t exactly add them. A very tl;dr explanation is to think of the * operator (without diving into matrix multiplication which is exactly what it does) as applying the CFrame on the right-hand of the * to the CFrame on the left-hand of the *.

For example,

Origin refers to the world position of Vector3.new(0, 0, 0) below I.e. The worldspace origin

CFrame.new(0, 10, 0) * CFrame.Angles(1, 0, 0)
What this does:
Starting at the origin, first move up 10 units from the origin, then apply the CFrame.Angles(1,0,0) to this which rotates the CFrame 1 radians around CFrame.new(0, 10, 0).RightVector.

Note that It would be 1 radians around CFrame.new(0, 10, 0).UpVector if it was CFrame.Angles(0, 1, 0) or 1 rad around CF.new(0, 10, 0).LookVector if it was CFrame.Angles(0, 0, 1)

CFrame.Angles(1,0,0) * CFrame.new(0, 10, 0)
What this does:
Starting at the origin, first rotate yourself 1 radians around the global x-axis. Then, apply CFrame.new(0, 10, 0) to it which moves you 10 units upwards along CFrame.Angles(1,0,0).UpVector. i.e. 10 units upwards in the direction it’s TopSurface is pointing towards.

Note that it would be 10 units rightwards along CFrame.Angles(1,0,0).RightVector, if it was right-multiplied by CFrame.new(10, 0, 0). It would also be 10 units along the lookvector if it was right-multiplied by CFrame.new(0, 0, 10).

CFrame.Angles(1.2, 0, 0) * CFrame.Angles(0, 2.1, 0) * CFrame.new(10, 0, 0)
What this does:
Starting at the origin, first rotate yourself 1.2 radians around the global x-axis. Then rotate around CFrame.Angles(1.2, 0, 0).UpVector by 2.1 radians. Then, move 10 units to the right along the direction of ( CFrame.Angles(1.2, 0, 0) * CFrame.Angles(0, 2.1, 0) ).RightVector.

Note that
CFrame.new(0, 10, 0) * CFrame.Angles(1, 0, 0)
is not the same as
CFrame.Angles(1,0,0) * CFrame.new(0, 10, 0).
Hence, you cannot really treat it as addition as addition is commutative. i.e. Doesn’t matter which way around you apply the + operation to two numbers, it will always be equal.
i.e. a + b = b + a

Look up visualizing composition of linear transformations for more. Also, look up three-dimensional linear transformations as well as two-dimensional (which is easier to understand before three-dimensional).

12 Likes

I found the best way to do make multiplications (or additions) with CFrames

local CF1,CF2=CFrame.new(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16),CFrame.new(1,2,3)
local CFA1,CFA2,CFA3={CF1:components()},{CF2:components()},{}
for i=1,16 do
    table.insert(CFA3,i,CFA1[i]*CFA2[i]) --The * is the operator
end
local CF3=CFrame.new(unpack(CFA3))

CF1 and CF2 are the two CFrames to multiply
CF3 is the result
Actually, It works…

5 Likes

How does this work? This just gives the error:
“RunService:fireRenderStepEarlyFunctions unexpected error while invoking callback: Invalid number of arguments: 16 - Studio 12:20:51.663 Invalid number of arguments: 16”