Trigonometry help

Hello there! I’m learning trigonometry and I need some help, I found some code on this forum that checks if the camera is looking at the sun, and it also uses trigonometry, I just don’t understand why they used math.acos(), and not other inverse functions, here is the code:

local camera = workspace.CurrentCamera;
local li = game.Lighting;

local rs = game:GetService("RunService");

local tweenService = game:GetService("TweenService");

local currentlyTweening = false

function Blur()
	if currentlyTweening then return end;
	local blur = li.Blur;
	tweenService:Create(blur,TweenInfo.new(2,Enum.EasingStyle.Sine), {Size = 24}):Play();
end;

function Unblur()
	if not currentlyTweening then return end;
	local blur = li.Blur;
	tweenService:Create(blur,TweenInfo.new(2,Enum.EasingStyle.Sine), {Size = 0}):Play();
end;

rs.Heartbeat:Connect(function()
	local cameraDirection = camera.CFrame.LookVector;
	local sunDirection = li:GetSunDirection();
	local angleBetweenTwoDirections = math.acos(cameraDirection:Dot(sunDirection))

	if  math.deg(angleBetweenTwoDirections) < 20 then
		Blur();
		currentlyTweening = true;
	else
		Unblur();
		currentlyTweening = false;
	end
end);

Any help would be appreciated :smiley:

I believe they used math.acos because the Dot product returns a number between -1 and 1, depending on the direction of both the sun and the camera. acos is the inverse of cos. As you probably already, cos is one of the ways you can get the length of a side, but we don’t want the length of a side, we want the angle, so we use acos to get the angle

Basically, they used math.acos because the dot product gives a number between -1 and 1 and an angle is required, since math.acos is the inverse of math.cos they used that to receive the angle

1 Like

This image best represents what that variable stands for.

image

The dot product itself can be represented by |x| × |y| × cos(θ) where |a| and |b| are represented as magnitudes and θ being the angle that variable is defining (theta).

However, the angle/theta is of course not given at first so that the code is trying to solve for θ by using acos which is just essentially the inverse of cosine.

4 Likes

Just to expand on this, explaining what dot product actually does


Dot product finds the length of the second vector “projected” onto the first (basically how long a line would be if you moved the second vector down on a line perpendicular to the first until it touched the first)
This action can be seen in the graphic below


The length of the orange-ish line would be whats returned from Dot

If you notice, this gives you a crucial piece of information in figuring out an angle- it gives you the length of one of the sides of a right triangle, a major part of trigonometry. We actually already know one of the side lengths already, because it makes a right triangle with the cameraDirection (which has a length of 1)
So, filling out what we know:


We know the cameraDirection has a length of 1, and the lower part of the right triangle has a length of the dot product of sunDirection and cameraDirection.
So, using the basic rules of trig, we could either use

  1. Sin(angle) = opp/hyp
  2. Cos(angle) = adj/hyp
  3. Tan(angle) = opp/adj

Individually looking at each of these, we can immediately cross out Sin and Tan because we do not know the opposite side.
Cos is the only one left, so you just fill out the formula:
The adjacent side (adjacent to the angle of interest, aka. the angle between the cameraDirection and sunDirection) is the side with the length of the dot product of sun and camera
The hypotenuse side is just the side with a length of 1

math.cos(angle) = adj/hyp
math.cos(angle) = sunDirection:Dot(cameraDirection) / 1
math.cos(angle) = sunDirection:Dot(cameraDirection)
angle = math.acos(sunDirection:Dot(cameraDirection))

So more or less to answer your original question, acos is used over asin or atan/atan2 simply becasue we don’t know enough information to use them. Dot product gives you the adjacent side length of the right triangle between two vectors, so you have to use acos in this instance.