简体   繁体   中英

How to find angle between two vectors on canvas?

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:)

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.

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:

  • A = 0|0
  • B = 0|-6
  • C = 5|2

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;

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)));

Example:

 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

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM