Weird dot product behavior?

So Im trying to make my own lookat kinda thing and im taking the arc cosine of the dot product to get the angle in radians but its just not working as intended

local p2 = script.Parent
local p1 = workspace.p1


game:GetService("RunService").Heartbeat:Connect(function()
	local position = (p1.Position - p2.Position).Unit
	local look = p2.CFrame.LookVector.Unit
	local result = position:Dot(look)
	p2.CFrame = CFrame.new(p2.Position) * CFrame.Angles(0,math.acos(result),0)
end)



Without rounding
image

The parts are both positioned in a way where the angle converted into degrees should returned should be zero for the Y Rotation but the dotproduct returns .99 which when I use the acos function on it and then convert it to degrees it doesnt give me exactly zero unless I use math.ceil on the dot product and then use the acos function

2 Likes

I was able to do this by doing the following:

local p2 = script.Parent
local p1 = workspace.p1

game:GetService("RunService").Heartbeat:Connect(function()
	local position = (p1.Position - p2.Position).Unit
	local angle = math.atan2(-position.Z, position.X) - math.pi/2
	p2.CFrame = CFrame.new(p2.Position) * CFrame.Angles(0, angle, 0)
end)

Just simple trigonometry. If you absolutely need dot product I could further investigate

1 Like

Here’s a solution using dot product, although I don’t recommend

local p2 = script.Parent
local p1 = workspace.p1

game:GetService("RunService").Heartbeat:Connect(function()
	local position = ((p1.Position - p2.Position) * Vector3.new(1, 0, 1)).Unit
	local look = (p2.CFrame.LookVector * Vector3.new(1, 0, 1)).Unit
	local result = position:Dot(look)
	local dir = (position - p2.CFrame.RightVector).magnitude <= (position + p2.CFrame.RightVector).magnitude and -1 or 1
	if result < 1 then
		p2.CFrame *= CFrame.Angles(0,math.acos(result) * dir,0)
	end
end)
3 Likes

Why wouldnt you recommend the dot product solution and also it works great but could you explain everything you changed in detail so I can grasp a better understanding of what i actually did wrong

2 Likes

Both solutions work, from what I’ve seen it seems simpler to use trig instead of making a more compliant dot product function.

Im asking how he actually got the dot product solution to work, unless you can expain

2 Likes

Why is he multiplying the vectors by this and then normalizing them?
image

Also I dont get what hes doing in this line exactly

local dir = (position - p2.CFrame.RightVector).magnitude <= (position + p2.CFrame.RightVector).magnitude and -1 or 1
1 Like

I think by changing the way you calculate the dot itself, kojo multiplies it by a vector3 before calculating the unit vector, I’m not that great with dot product so it’s best that they explain it lool.

1 Like

The second one calculates the direction to look at based on the differences of the right vectors, so it can tell which way to look?

Also why does he have a less then or equal to symbol in the direction variable is it an if?

1 Like

What do you mean? It’s a one line if statement? I don’t understand

Yeah usually you dont have those symbols in variables so is he comparing?

Also why did he multiply by Vector3.new(1,0,1) specifically?

1 Like

Yes, it compares the two rightvectors and the magnitude. It’s basically:

local WhatToPrint = ((1+1 == 2) and “it equals two”) or “it doesn’t equal two”

Because 1+1 is 2, what to print is set to “it equals two”

1 Like

(Thats the logic behind one line if’s btw)

1 Like

This one I’m not too sure on, maybe because of something to do with acos?

1 Like

Hm, alright well thanks for the brief explanation of this, maybe if he responds something will be less foggy

1 Like

No probs, I’m not great with math so I can’t really help much, anyways enjoy the rest of ur day!

2 Likes

I did this so that the vectors are on a X and Z plane (so its basically 2d vector). Since you’ll only be rotating around the Y axis I made it this way.

As you know, using dot product you could get the angle between. However it doesn’t tell you which direction (ex: dot product of 45° right vs 45° left is both image ). I used a hacky way of determining the direction by comparing which side vector is closest to point toward the target.


image
(vector A is closer to pointing towards the object than vector B; therefore it should turn right).

1 Like

Ohhh alright thanks alot this makes alot of sense now

How would I change this so it would work on the Y Axis like moving the block up and it still looking at it but its Y Position

1 Like
local p2 = script.Parent
local p1 = workspace.p1

game:GetService("RunService").Heartbeat:Connect(function()
	local position = (p1.Position - p2.Position).Unit
	local angle = math.atan2(-position.Z, position.X) - math.pi/2
	local pitch = math.asin(position.Y)
	p2.CFrame = CFrame.new(p2.Position) * CFrame.fromEulerAnglesYXZ(pitch, angle, 0)
end)
1 Like