Let’s say you have a CFrame cf
and a Vector3 position p
:
local cf: CFrame
local p: Vector3
If you want to get the offset of the position p
relative to the rotation of the CFrame cf
, you would do:
local relativeOffset = cf:VectorToObjectSpace(p)
If you were to make a function that returns the offset of a Vector3 relative to the orientation of a CFrame, it would look something like this:
local function offsetRelativeToOrientation(cf: CFrame, p: Vector3): Vector3
local p0, r, u, l = cf.Position, cf.RightVector, cf.UpVector, -cf.LookVector
local px, py, pz = p.X, p.Y, p.Z
local p0_x, p0_y, p0_z = p0.X, p0.Y, p0.Z
local r_x, r_y, r_z = r.X, r.Y, r.Z
local u_x, u_y, u_z = u.X, u.Y, u.Z
local l_x, l_y, l_z = l.X, l.Y, l.Z
local d_x, d_y, d_z do
local d = p - p0
d_x = d.X
d_y = d.Y
d_z = d.Z
end
--[[ solving matrix equation:
solving for x, y, z
x * r + y * u + z * l = p - p0
Equivalent matrix equation:
| r_x u_x l_x | | x | | d_x |
| r_y u_y l_y | * | y | = | d_y |
| r_z u_z l_z | | z | | d_z |
Thus,
| r_x u_x l_x d_x | | 1 0 0 x |
rref | r_y u_y l_y d_y | = | 0 1 0 y |
| r_z u_z l_z d_z | | 0 0 1 z |
turning this matrix into its row reduced echelon form
gives us the following equations
]]
return Vector3.new(
(-d_x*l_y*u_z + d_x*l_z*u_y + d_y*l_x*u_z - d_y*l_z*u_x - d_z*l_x*u_y + d_z*l_y*u_x)/(l_x*r_y*u_z - l_x*r_z*u_y - l_y*r_x*u_z + l_y*r_z*u_x + l_z*r_x*u_y - l_z*r_y*u_x),
(d_x*l_y*r_z - d_x*l_z*r_y - d_y*l_x*r_z + d_y*l_z*r_x + d_z*l_x*r_y - d_z*l_y*r_x)/(l_x*r_y*u_z - l_x*r_z*u_y - l_y*r_x*u_z + l_y*r_z*u_x + l_z*r_x*u_y - l_z*r_y*u_x),
(d_x*r_y*u_z - d_x*r_z*u_y - d_y*r_x*u_z + d_y*r_z*u_x + d_z*r_x*u_y - d_z*r_y*u_x)/(l_x*r_y*u_z - l_x*r_z*u_y - l_y*r_x*u_z + l_y*r_z*u_x + l_z*r_x*u_y - l_z*r_y*u_x)
)
end
print(offsetRelativeToOrientation(CFrame.new(), Vector3.new(3, 0, 0))) --// 3, 0, 0
print(CFrame.new(0, 0, 0):VectorToObjectSpace(Vector3.new(3, 0, 0))) --// 3, 0, 0
print(offsetRelativeToOrientation(CFrame.Angles(math.rad(30), 0, 0), Vector3.new(1, 0, 0))) --// 1, 0, 0
print(CFrame.Angles(math.rad(30), 0, 0):VectorToObjectSpace(Vector3.new(1, 0, 0))) --// 1, 0, 0
print(offsetRelativeToOrientation(CFrame.Angles(0, math.rad(30), 0), Vector3.new(5, 0, 0))) --// 4.33012..., 0, 2.5
print(CFrame.Angles(0, math.rad(30), 0):VectorToObjectSpace(Vector3.new(5, 0, 0))) --// 4.33012..., 0, 2.5