How do I return a negative angle value if a part is facing away 'leftwards' from a point?

I accidentally had the directions flipped. Please use the following code which fixes it.

function getDirectionalTan(PerspectiveCFrame, XDistance, ZDistance)
	local tan = 0
	local lookVectorX = math.abs(math.round(PerspectiveCFrame.lookVector.X))
	if lookVectorX == 0 then--Player looking Z direction so use X as opposite, and X as adjacent
		tan = (XDistance/ZDistance)--tan number
	else--Player looking X direction so use Z as opposite, and X as adjacent
		tan = (ZDistance/XDistance)--tan number
	end

	return tan--return tan number
end

function getAngle(CameraCFrame, PartPosition)
	local CameraPosition = CameraCFrame.Position
	local XDistance = PartPosition.X - CameraPosition.X
	local ZDistance = PartPosition.Z - CameraPosition.Z

	local angle = math.atan(getDirectionalTan(CameraCFrame,XDistance, ZDistance))--Run tan math function

	return angle
end

local angle = getAngle(Camera.CFrame, Part.Position)--fix paraemetre to ur variables, and tadaaa

This doesn’t seem to function correctly. The angles outputted are very inaccurate and doesn’t invert the angle when I rotate the camera left.

It only seems to only output 0 or 90 degrees when I spin the blue block while being in-line with the red block

while true do
	wait()
	local angle = getAngle(Camera.CFrame, Part.Position)--fix paraemetre to ur variables, and tadaaa
	print(math.deg(angle))	
end

You can use cross products:

local modifier = LookToPoint:Cross(CameraLookVector).Y

This will be a positive or negative value to tell you which side the part is on. Not sure whether left is negative or positive or whatever, butb you can mess around as needed I’m sure.

1 Like

Wow. I haven’t even thought about using the Cross product. I can easily determine from which side the part is facing towards the block. Thank you very much!

local function GetAngleBetween(PosA, PosB)
	return math.acos(math.clamp(PosA:Dot(PosB), -1, 1))
end

while true do
	wait()
	local CameraLookVector = script.Parent.CFrame.LookVector
	local LookToPoint = (workspace.RedBlock.Position - script.Parent.Position).Unit
	
	local AngleBetween = GetAngleBetween(CameraLookVector, LookToPoint)
	
	local Modifier = -math.clamp(LookToPoint:Cross(CameraLookVector).Y, -1, 1) -- Determines whether we are looking on the left side or the right side of the angle

	-- Round to whole number
	if Modifier > 0 then
		Modifier = 1
	elseif Modifier < 0 then
		Modifier = -1
	end
	
	print(math.deg(AngleBetween * Modifier))
end
3 Likes

Sorry I was using that for Y,X/Z and changed it and didn’t think about how it would be inaccurate. However, just realize you’re attempting to use direction/lookVector not just position. For this, you can use cos = adjacent/hypotenuse. However, you would also figure out where the directions intersects. as seen in the image below. Also assuming the camera point is straight line changing line, and redblock is a fixed position line. You would want to use camera direction as the hypotenuse. Since it can rotate and redblock will never directly hit the camera point, it will intersect.

Also since redblock orientation is (0,0,0). You could just use your camera rotation as the angle. since either way no matter where it intersects. it will travel at the same angle. As seen below in the image

math.acos=(adjacent/hypotneus)

1 Like

So conclusion just angle = camera orientation.Y + blockOritentation.Y. In case you rotate the block. it will produce the same angle. A block rotate at 45 degrees and with a camera orientation at 90 degrees. there look vector lines of the intersection will produce an intersection point of 45 degrees. Example image below

1 Like