Why is CFrame.new(1,1,1) * CFrame.new(2,2,2)
equal to CFrame.new(3,3,3)?
I'm going to back-up and first answer a related question:
Why is Vector3.new(1, 2, 3) + Vector3.new(4, 5, 6) equal to Vector3.new(5, 7, 9)?
Vector3s represent two kinds of values:
In general, the .x
and .y
and .z
of absolute coordinates don't really mean much. How "big" they are just means how far they are from (0, 0, 0) -- and you probably build your games not really caring where (0, 0, 0) is anyway. Their sign gives you an idea of which "direction" they are from the origin, but again, who cares about the origin?
The .x
and .y
and .z
of relative coordinates means everything. "one stud below" is Vector3.new(0, -1, 0)
-- you probably have relative coordinates like this all throughout your code.
Let's say we want to spawn a light 10 studs above a player's head
. What does the code for that look like?
local p = Instance.new("Part", workspace) p.Position = head.Position + Vector3.new(0, 10, 0) Instance.new("PointLight", p)
When we say "10 studs above", we are describing a position (p.Position
) relative to another position (head.Position
).
That relative Vector3 is Vector3.new(0, 10, 0)
.
If we do <absolute> + <relative>, we get another absolute vector.
If you have two relative positions, e.g., 10 steps forward Vector3.new(0, 0, -10)
and 10 steps to the right Vector3.new(10, 0, 0)
, you could take that like this:
person.Position = foo person.Position = person.Position + Vector3.new(0, 0, -10) person.Position = person.Position + Vector3.new(10, 0, 0)
This is really just doing
person.Position = foo + Vector3.new(0, 0, -10) + Vector3.new(10, 0, 0)
You can combine the two relative vectors into a single relative vector instead:
motion = Vector3.new(0, 0, -10) + Vector3.new(10, 0, 0) -- equal to Vector3.new(10, 0, -10) person.Position = foo + motion
Algebra tells us that if p = h + r
, then we should be able to do p - h = r
.
In fact, we can print
print(p.Position - head.Position) --> 0, 10, 0
In general, you can get the relative displacement between two absolute positions by subtracting them. This is useful for, e.g., getting the distance to a target:
local displacement = zombie.Position - victim.Position if displacement.magnitude < 10 then -- the relative difference in position -- between `victim` and `zombie` -- is less than 10 in magnitude -- i.e., they're nearby end
Vectors are in general defined by the behavior of +
and -
to behave as they do here.
Actually, vectors are defined in terms of addition +
and inverse -
. When you write a - b
, really what that means is a + -b
. This is significant in the analogy CFrames.
CFrames are similar, with a few wrinkles.
CFrames can be relative or absolute;
part.CFrame
is an absolute CFrame; CFrame.new(0, 1, 0)
is a relative CFrame describing "up" one stud.
You can "apply" a relative CFrame by using *
instead of +
:
part.CFrame = part.CFrame * CFrame.new(0, 1, 0)
Just like with Vector3s, you can "combine" two relative CFrames into another relative CFrame, by using *
:
part.CFrame = part.CFrame * CFrame.new(10, 0, 0) part.CFrame = part.CFrame * CFrame.new(0, 0, -10) -- same thing as local motion = CFrame.new(10, 0, 0) * CFrame.new(0, 0, -10) part.CFrame = part.CFrame * motion
Because of how CFrames are constructed, CFrame.new(a, b, c)
is the same thing as CFrame.new(Vector3.new(a, b, c))
-- we know how Vectors get combined (add the components), so the corresponding Vector3 +
happens when you *
the CFrames constructed in that way.
Note that CFrames are a bit different; with vectors, u + v
is the same as v + u
. That's not the case with CFrames; x * y
is NOT1 the same as y * x
(and that's why CFrames don't also use +
).
However, there isn't a corresponding -
for *
. In mathematics, we write x^-1, but that's not an acceptable notation in code. CFrames have an :inverse()
method which makes the relative CFrame that "undoes" a CFrame. Thus
part.CFrame * blah * blah:inverse() -- same thing as part.CFrame
In general, they're different, but they can be the same. For CFrame.new(x, y, z)
's, they behave just like vectors -- a * b
and b * a
will be the same in that case. Try using CFrame.Angles
as an example where they're different ↩
Locked by AZDev, Link150, DepressionSensei, and shayner32
This question has been locked to preserve its current state and prevent spam and unwanted comments and answers.
Why was this question closed?