Basically what im trying to do is make the red part have the same orientation as the purple part but only for the Y axis. the red part should keep their X and Z orientation axis, but have it face the same direction as the purple part on the Y axis. the golden part is the expected result.
How can i generate a new CFrame (without creating a new part) that is the same as the golden part given only both the red and purple part’s CFrame? any help is appreciated.
I would use this CFrame rotation between two vectors function from this tutorial. Don’t focus too much on the quaternions you can still the CFrame.fromAxisAngle which tbh is more understandable though quaternions are cooler.
Edit: @20amir02 here is the newer code that should work if you use this method to align one axis to another, the issue with the previous is that this rotation is relative to world space and so the rotation must happen before the red part CFrame. CFrame order of operation stuff. The + position is there in order to maintain the parts current position, and the .CFrame - .CFrame.Position is to add the previous parts rotation into account.
local PurplePart = workspace.Part2--define
local RedPart = script.Parent--define
local function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
end
local addRotation = getRotationBetween(RedPart.CFrame.UpVector, PurplePart.CFrame.UpVector,Vector3.new(0,1,0))
RedPart.CFrame = addRotation*(RedPart.CFrame-RedPart.CFrame.Position)+RedPart.CFrame.Position
Old not working code
local PurplePart = --define
local RedPart = --define
local function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
end
RedPart.CFrame *= getRotationBetween(RedPart.UpVector, PurplePart.UpVector,Vector3.new(0,1,0))
This should apply an additional rotation to the red part which should align the red parts up vector with the purple parts UpVector.
The UpVector should represent the y axis of the part as expected.
The third parameter which is (0,1,0) is arbitrary meaning it can be anything.
Case 2, from the tutorial
If the u and v are complete opposites i.e. u == -v, then we choose an arbitrary axis and rotate by 180 degrees.
i can’t seem to get your solution to work. im not really that experienced in these advanced stuff
though ive been at it with jacky’s solution with ToOrientation(), using CFrame.Angles() and CFrame.fromOrientation() both doesn’t give me the expected results.
I ran this code:
local d = math.deg
local part1 = workspace.Part1 --Red Part
local part2 = workspace.Part2 --Purple Part
local x1,y1,z1 = part1.CFrame:ToOrientation()
local x2,y2,z2 = part2.CFrame:ToOrientation()
part1.CFrame = CFrame.new(part2.Position) * CFrame.fromOrientation(d(x1),d(y2),d(z1))
though it seems to be correct, the red parts X orientation is slightly different!
and the difference is much more noticable in other cases.