Find a rotated orientation

I’m trying to make a simple mirror, and so I need to find the rotated orientation.
I’ll show you what I mean.
So say I have this red part, that’s reflected through the mirror.
I can’t just rotate everything by 180 degrees


Because that’s not how mirrors work

Even in 3D it looks weird.

So, I want it to be reflected like it would be in real life. I need the maths to achieve this.

to get the rotation you should be able to just times it by -1 and to get positions just get position of the mirror and object and get the offset by mirror.Position - object.Position and subtract the offset with the X or Z

If we have a given direction vector (in this case, the LookVector of the part) and the plane normal of the mirror then we can calculate a reflected vector.

Our plane normal in this case, will be the LookVector of the semi transparent part you showed in the image. To get the reflected vector, first we need to dot the plane normal and part LookVector.
local dot = part.CFrame.LookVector:Dot(planeNormal)

Then, we can solve for the final vector by doing
local reflected = 2 * dot * planeNormal - part.CFrame.LookVector

To construct the final part cframe, we can just get the positional offset by doing
local positionalOffset = part.CFrame:PointToObjectSpace(mirrorPosition)

then make the cframe like so:
local reflectedCFrame = CFrame.new(positionalOffset) * CFrame.lookAt(Vector3.new(), reflected)

NOTE: I haven’t tested this code so please reply with any issues!

5 Likes

Alright, sorry to get back to you late, but I’ve done a couple changes and it works well now.

https://gyazo.com/ca534fb58c786a9597c66efb2efa6947

I’ve attached a place file with the parts and script.

Here’s the final code:

local RunService = game:GetService('RunService')

local mirror = workspace.Mirror
local part = workspace.Part
local reflectedPart = workspace.ReflectedPart

RunService.Stepped:Connect(function(pt, dt)
	local planeNormal = mirror.CFrame.LookVector
	
	local forwardDot = part.CFrame.LookVector:Dot(planeNormal)
	local reflectedFoward = 2 * forwardDot * planeNormal - part.CFrame.LookVector
	
	local upDot = part.CFrame.UpVector:Dot(planeNormal)
	local reflectedUp = 2 * upDot * planeNormal - part.CFrame.UpVector
	
	local positionalOffset = mirror.CFrame:PointToObjectSpace(part.Position)
	
	positionalOffset = (mirror.CFrame * CFrame.new(positionalOffset.X, positionalOffset.Y, -positionalOffset.Z)).Position
	
	local reflectedCFrame = CFrame.new(positionalOffset) * CFrame.lookAt(Vector3.new(), reflectedFoward, reflectedUp)
	
	reflectedPart.CFrame = reflectedCFrame
end)

EDIT: I forgot to take into account the UpVector, so the mirror was behaving weirdly. I’ve attached new code and a new place.

mirror.rbxl (29.1 KB)

1 Like