【问题标题】:How to find angle between two vectors on canvas?如何在画布上找到两个向量之间的角度?
【发布时间】:2019-05-15 10:35:39
【问题描述】:

我需要在画布上找到两个向量之间的角度。 我在下面附上了一些例子:

你能告诉我一些公式吗?我的学校数学有问题:)

【问题讨论】:

  • 是向量还是段?
  • 我有每一行的起点,所以我猜它是一个向量
  • 那么 5''0' 和 4''3' 的长度是多少?还是那些坐标?
  • 这是它们的长度。
  • 那么图片上的0坐标在哪里?

标签: javascript math canvas geometry


【解决方案1】:

基本上,您需要将连接两个向量的点设为原点,其中 x=0 和 y=0。

看看这张照片:

现在我们可以说ABC点的x和y值为:

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

要计算两者的反正切,我们可以使用 Math.atan2() 函数。请注意,atan2 的第一个参数必须是 y 值。

var firstAngle = Math.atan2(-6, 0);
var secondAngle = Math.atan2(2, 5);

并通过减法得到它们的差异

var angle = secondAngle - firstAngle;

这将返回一个弧度值,您可以像这样转换为度数:

angle = angle * 180 / Math.PI;

【讨论】:

  • 0|-6 和 5|2 不是点,而是长度。但这没关系。我会尝试发表评论。谢谢!
  • 我使用了这个公式,但是当我像第一张图片一样构建形状时,我得到了 0。但真正的角度是 90。
  • 如果我将 -5|0 用于左上角,将 0|5 用于右下角,我会得到 90 度 - 正如预期的那样。
  • 对于 C 5|2 不是正确的坐标。那就是长度。
  • 不要混淆我不是在谈论长度(这是向量的大小)。我说的是从中心点 A 开始的方向。在我上面的回答中,你必须向右移动 5 个街区,向下移动大约 2 个街区才能从 A 点到 C 点 -> 这就是矢量。巧合的是,您图片中的长度也显示为 5" 2'。
【解决方案2】:

首先,您需要标准化这两个向量。

完成后就可以了

angle = arcos(v1•v2)

其中“angle”是您要找到的角度,“arcos”是余弦函数的反函数,“•”是点积运算符

小心,这只会返回相对角度和原始角度。您将无法知道哪个矢量在左侧,哪个矢量在右侧。

【讨论】:

  • 如何计算这个 v1 * v2? V1 和 V2 由两点组成。
  • 即使您不对其进行规范化,这也有效。如果您使用右手法则,您可以从左到右:取叉积。标志告诉你左或右。
【解决方案3】:

如果您需要2D (z=0) 和3D 支持,您可以使用Dot product

const dot = (p1, p2) => p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;

使用平方幅度 (magSq),我们可以计算幅度:mag = Math.sqrt(magSq)

const magSq = ({x, y, z}) => x ** 2 + y ** 2 + z ** 2;
const mag = Math.sqrt(magSq(p));

现在我们可以计算Dot product 并在之后“标准化”它。 现在使用acos() 获取角度:

const angle = Math.acos(dot(p1, p2) / Math.sqrt(magSq(p1) * magSq(p2)));

我们也可以使用Math.hypot(),这是mag的专用JS函数:

const mag = (p) => Math.hypot(p.x, p.y, p.z);

… 并获得角度:

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

【讨论】:

    【解决方案4】:

    老问题。但我找到了很好的解决方案。假设我们有 4 个点形成 2 个向量。点(P0,P1,P2,P3),则P0P1与P2P3的夹角为:

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

    【讨论】:

      猜你喜欢
      • 2011-07-03
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多