Reputation: 297
I need to find the angle between two vectors on my canvas.
I have attached some examples below:
Could you advise me some formula? I have problems with school math :)
Upvotes: 1
Views: 8155
Reputation: 938
Old question. But I found good solution. Let say we have 4 points form 2 vectors. Points (P0, P1, P2, P3), then the angle of P0P1 and P2P3 is:
function angle2Vectors(ps) {
const v1 = { x: ps[1].x - ps[0].x, y: ps[1].y - ps[0].y };
const v2 = { x: ps[3].x - ps[2].x, y: ps[3].y - ps[2].y };
const l1_l2 = len(ps[1], ps[0]) * len(ps[3], ps[2]);
const v1_v2 = v1.x * v2.x + v1.y * v2.y;
const cos = v1_v2 / (len(ps[1], ps[0]) * len(ps[3], ps[2]));
const angCos = Math.acos(cos) * (180 / Math.PI);
const _v1_v2_ = v1.x * v2.y - v2.x * v1.y;
const sin = _v1_v2_ / l1_l2;
const angSin = Math.asin(sin) * (180 / Math.PI);
return angCos * Math.sign(angSin);
}
Upvotes: 1
Reputation: 2822
If you need 2D (z=0
) and 3D support, you could use the Dot product
const dot = (p1, p2) => p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
With a square magnitude (magSq
), we can calc the magnitude: mag = Math.sqrt(magSq)
const magSq = ({x, y, z}) => x ** 2 + y ** 2 + z ** 2;
const mag = Math.sqrt(magSq(p));
Now we can calc the Dot product and "normalize" it afterwards.
Now use acos()
to get the angle:
const angle = Math.acos(dot(p1, p2) / Math.sqrt(magSq(p1) * magSq(p2)));
We could also use Math.hypot()
, a dedicated JS function for mag
:
const mag = (p) => Math.hypot(p.x, p.y, p.z);
… and get the angle:
const angle = Math.acos(dot(p1, p2) / (mag(p1) * mag(p2)));
let a = {x: 0, y: -6, z: 0};
let b = {x: 5, y: 2, z: 0}; // set z != 0 for 3D
let dot = (p1, p2)=> p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
let magSq = ({x, y, z}) => x ** 2 + y ** 2 + z ** 2;
let angle1 = Math.acos(dot(a, b) / Math.sqrt(magSq(a) * magSq(b)));
console.log('1. Angle:', angle1); // 1.9513027
// ... or
let mag = ({x, y, z}) => Math.hypot(x, y, z);
let angle2 = Math.acos(dot(a, b) / (mag(a) * mag(b)))
console.log('2. Angle:', angle2); // 1.9513027
Upvotes: 3
Reputation: 12891
Basically you need to make the point which connects your two vectors the origin, where x=0 and y=0.
Take a look at this picture:
Now we can say that the x and y values of the points A, B and C are:
To calculate the arctangent of both we can utilize the Math.atan2() function. Please note that the first parameter for atan2 must be the y value.
var firstAngle = Math.atan2(-6, 0);
var secondAngle = Math.atan2(2, 5);
and get the difference of them by subtraction
var angle = secondAngle - firstAngle;
This will return a radian value you can convert to degrees like this:
angle = angle * 180 / Math.PI;
Upvotes: 7
Reputation: 145
First you'll need to normalize the two vectors.
Once that's done you can do
angle = arcos(v1•v2)
where "angle" is the angle you want to find, "arcos" is the inverse of cosine function and the "•" is the dot product operator
Be careful, this will return only the relative and raw angle. You won't be able to know which vector is on the left and which one is on the right.
Upvotes: 2