Dot Product returning very large value

I am new to dot product and while I was trying to see the result of the product, it printed a very large number. I assumed it was because the script was doing a.x * b.x + a.y * b.y + a.z * b.z. But aren’t dot products supposed to return a value under 1? I don’t know if I am doing the equation right. Here is my script

local a = game.Workspace.Alpha
local b = game.Workspace.Beta

local function caculateDot(a,b)
	return a.Position:Dot(b.Position).Magnitude
end

while wait(1) do
	print(caculateDot(a,b))
end

I don’t see why they should return a value below 1. The dot product is a.x * b.x + a.y * b.y + a.z * b.z

:Dot() already returns a number; in this case, you would be doing e.g. 0.75.Magnitude, which is not possible. I’m baffled that this doesn’t raise an error.

And yes, a dot product absolutely can be larger than 1. You’re probably thinking of sin and cos.
The dot product cannot be larger than the longer vector. If a and b are the same vector, then the most it can be is a.Magnitude, for example.

I think you should look at a visual explanation of what the dot product calculates:
Dot product
The point A is projected onto the “line” from origin to B,
and the dot product is the distance from the origin to where the projection ends up.
If OA and OB are perpendicular, the dot is 0.

The dot product is the same regardless of whether you do a:Dot(b) or b:Dot(a)

Edit:
The “origin” in your case is Vector3.new(0, 0, 0), because you’re using Dot on parts’ actual world positions. If your parts are really far from the center of the world, then the dot product will be really big, because it’s operating on really long vectors.

1 Like

thanks for informing me. Also about the magnitude I forgot to remove that before I posted that here.

So how can I use this product to make some cool things, like for example when people use the dot product for vision it is always under 1. How did they make the product under 1 and not some crazy number like my result

Alright I think I understand Dot Product more now. Thanks for the help.

The number you get is crazy, but 100% correct. There is absolutely nothing wrong with the dot product, but rather with how you are using it.

You definitely need to understand that the dot product is actually relative to three points, not just a and b. The third point is the point that they’re both relative to.

Let’s say you want to check whether your Alpha brick is “in front” of your Beta brick.

Code that does this (so I can explain how and why it works):

function isBehind(partA, partB)
	local posA = partA.Position -- A's position. E.g. Vector3.new(17, 5, 9)
	local posB = partB.Position -- B's position. E.g. Vector3.new(20, 5, 8)
	local dirBForward = partB.CFrame.LookVector -- The direction that B is facing. E.g. Vector3.new(1, 0, 0). This will never be longer than 1 unit, it's just a pure direction.
	local dirBToA = posA - posB -- The direction from B to A. In this case, Vector3.new(-3, 0, 1). This can be any length, in fact, its length is the distance between B and A, and its direction points from B to A.
	
	-- ???
	local dot = dirBForward:Dot(dirBToA)
	print("Dot is " .. dot)
	return dot < 0
end

while true do
	if isBehind(workspace.Alpha, workspace.Beta) then
		print("Alpha is behind Beta")
	else
		print("Alpha is in front of Beta")
	end
	wait(0.5)
end

Make sure you can easily know what’s the front face of the Beta brick, such as with a decal that’s set to be on the Front surface.
Run the script and move the bricks around.

Dot should be negative if Alpha is behind Beta, positive in front of it and very small when it’s to the side.

The reason why this one works is because dirBForward and dirBToA are both relative to B’s position.
Vectors do not have a “starting position”. Only a direction and length.
They both point from B’s position, to something. They were both derived from B’s location somehow. Both vectors are relative to B.
When dealing with dots, crosses etc. you always want to know what the world spins around.

Now let’s do it wrong.
Replace dirBForward:Dot(dirBToA) with posA:Dot(posB).
This should act the same as the code you posted.
It acts like this because it’s doing the dot product of garbage. Garbage in, garbage out.
But it helps to know if the two bricks are on opposite sides of the world! Put a brick on the center of the world (that’s 0, 0, 0). Move Alpha and Beta around. The script should definitely print “behind” if the center of the world is between Alpha and Beta.
All we had to do to make it work was move the center of the world to the position of Beta.

So now you can use the dot product to find how two directions relate. If the directions are almost the same, then the dot is high and positive. If the directions are opposite each other, then the dot product is high and negative. If the directions are almost perpendicular, then it will be low.

To ensure the dot product can’t be higher than 1, get the unit vector (vector of length 1) of your directions.
dirBForward:Unit():Dot(dirBToA:Unit())
You don’t actually need dirBForward:Unit() because it’s already guaranteed to be a unit vector.

Other things you can do with dot:

To check whether two players are facing about the same way, check whether A’s direction dot B’s direction is positive. That means they aren’t facing opposite each other (although they might be forming almost an L shape)

If you have a hallway and want to know how far in it a player is, then you need to know the positions of both ends of it and the position of the player.
The span of the hallway will be hallwayEnd - hallwayStart, and the span between the start of the hallway and the player will be playerPos - hallwayStart.
The dot product of these two will be… really long and make no sense. So use :Unit() on the span of the hallway to get the amount of studs the player is into the hallway.
hallwaySpan:Unit() is just the direction of the hallway.
hallwaySpan:Unit():Dot(playerSpan) is how much of the player’s movement has been in the hallway’s direction.
hallwaySpan:Unit():Dot(playerSpan) / hallwaySpan.Magnitude is 0 when at the entrance, 1 at the end and 0.5 in the middle of the hallway.

This is how you check how whether you’re looking toward the sun using just the dot product.

You check how high the direction toward the sun -dot- direction your camera is looking is. If it’s positive and somewhat high, then the directions are close. The dot cannot be higher than 1 here because both directions are unit vectors (they are 1 stud long)

This post is a mess, I just kept on writing things and could not abandon it

1 Like