Hello, I’m currently trying to make a snippet of code that will take one CFrame and perfectly correct it using Vector maths so that it perfectly faces another CFrame.
Context
The reason I wouldn’t simply set the CFrame to its counterpart and rotate it about an axis is because I eventually plan for this to be a part of a robust building-piece snapping system; the end goal being for the acted-upon “snap points” (represented by the CFrames) to be snapped to one-another among arbitrary angular increments (i.e, snap points of two wall pieces snapping to connect to each other at flush or 90-degree angles). So in essence, say a piece is being placed and it is going to be snapped to another piece; the already-placed piece’s snap point would ensure that the new wall was flush with it’s floor plane, but the wall could still be freely rotated on a single axis relative to the point. It’s a bit hard to explain but I hope that explains it.
Tl;dr I would like full control over each axis that is set so that I can choose to only correct certain ones.
This is what I have tried previously, using Cross and Dot products sequentially with each axis in an arbitrary order.
-- cframe1: The cframe that will be corrected
-- cframe2: The cframe that cframe1 will be corrected to
function module:SnapPoints(cframe1, cframe2)
local newCf = CFrame.new(cframe2.p) * (cframe1 - cframe1.p)
local applySnap = function(vectorName, axisName)
local currentVector = newCf[vectorName]
local desiredVector = cframe2:inverse()[vectorName]
local cross = currentVector:Cross(desiredVector)
local theta = math.acos(currentVector:Dot(desiredVector))
if cross.magnitude ~= 0 then
local axis = cross.unit
newCf *= CFrame.fromAxisAngle(axis, theta)
end
end
applySnap("rightVector", "x")
applySnap("lookVector", "z")
applySnap("upVector", "y")
return newCf
end
It works when cframe1 is only off-grid by a single axis, but when multiple axes need to be corrected, it fails to do so properly.
I have no idea if using Cross & Dot Product are the best way to go about this, or if even going about it on a per-axis way is a good idea. I’m not sure why this solution isn’t working as I intend, since it both gets an axis of rotation and an angle to follow, and applies it to the CFrame for every axis. Vector math has always been crazy to me, so any possible explanation would be appreciated!