# 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

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?

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 ). I used a hacky way of determining the direction by comparing which side vector is closest to point toward the target.

(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