Angle between two points

For my game I need to get the angle between two vectors;

Vector2.new(mouse.Hit.Position.X,mouse.Hit.Position.Z)

and

Vector2.new(char["Right Arm"].CFrame.UpVector.X,char["Right Arm"].CFrame.UpVector.Z)

I have tried doing angle = math.atan2(vec2.Y,vec2.X) - math.atan2(vec1.Y,vec1.X) where vec2 is the upvector stuff and vec1 is the other vector.

However this is producing unreliable results as I need to rotate the character’s humanoid root part by the angle to align the gun to point towards the mouse hit position and when I use this method to get the angle needed to rotate, the character flashes and glitches around.

1 Like

Angle between two vectors:

function Angle(vectorA, vectorB)
   return math.acos(vectorA:Dot(vectorB) / (vectorA.Magnitude * vectorB.Magnitude))
end

If you can guarantee that both vectors are unit vectors, then you can remove the divisor:

function Angle(vectorA, vectorB)
   return math.acos(vectorA:Dot(vectorB))
end
15 Likes

EgoMoose goes decently in-depth with solving the angle between two vectors here:

That’s where I learned to use dot product at least. So if OP is struggling to understand why this works, give this video a look!

10 Likes

Good add! Understanding why things work is really important

3 Likes

I’m getting an issue now where if I do composition of the humanoid root part’s CFrame with CFrame.Angles(0,anglebetweenvectors,0) I’m getting a black screen and seconds later my character is dying? (I assume I’m being flung somehow)

EDIT: I’m printing the output of the angle between two vectors function and I’m getting -NAN(ind)?

I would write this like so for convenience, a bit shorter:

function Angle(vectorA, vectorB)
   return math.acos(vectorA.Unit:Dot(vectorB.Unit))
end

Somehow I’m getting a “Not a number” return value from the function for the first few iterations. How do I avoid that?

That means your input to math.acos is not within [-1, 1].

Make sure you are feeding non-zero vectors to the function and that you either use the function that takes both non-unit and unit vectors, or use the function that takes unit vectors but then ensure that your inputs are actually unit vectors (= length 1).

If that doesn’t solve the issue, it might be because of a floating point error, in which case clamp the value you feed to math.acos to be within [-1, 1]:

math.acos(math.clamp(..., -1, 1))
2 Likes