【问题标题】:comparing two angles比较两个角度
【发布时间】:2011-02-22 22:28:20
【问题描述】:

给定平面上的四个点A,B,X,Y,我希望确定以下两个角度中的哪一个更小∢ABX∢ABY

角度∢ABX 定义为BX 的角度,此时AB 被转换为位于开放段(-∞,0] 上。直观地说∢ABX是指访问顶点B后左转时的角度。

我宁愿不使用cossqrt,以保持准确性并最大限度地降低性能(代码将在嵌入式系统上运行)。

A=(-1,0),B=(0,0)的情况下,我可以通过计算向量X,Y的点积来比较∢ABX∢ABY这两个角度,并观察它的符号。

在这种情况下我能做的是:

  1. 判断ABX是右转还是左转
  2. 如果ABX 向左转,检查YA 是否在线段BX 的同一侧。如果它们是 - ∢ABX 小于 ABY
  3. 如果ABX右转,那么YABX的同一侧表示∢ABX大于∢ABY

但这对我来说似乎太复杂了。

有更简单的方法吗?

【问题讨论】:

  • 请注意,仅当您的位置已经准确知道时,保持准确性才有意义,例如表示为整数或有理数。但还有其他避免平方根的正当理由,即性能。

标签: math vector geometry


【解决方案1】:

这是一些伪代码。不检测两个角度相同的情况。也不处理角度方向,例如假设所有角度都是

v0 = A-B
v1 = X-B
v2 = Y-B

dot1 = dot(v0, v1)
dot2 = dot(v0, v2)

if(dot1 > 0)
  if(dot2 < 0)
    // ABX is smaller
  if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2, v2) )
    // ABX is smaller
  // ABY is smaller

if(dot2 > 0)
  // ABY is smaller
if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2,v2) )
  // ABY is smaller
// ABX is smaller

请注意,如果您允许取两个平方根,那么大部分痛苦都会消失。

【讨论】:

    【解决方案2】:

    通过做将原点放在 B 上

    X = X - B
    Y = Y - B
    A = A - B
    

    编辑:您还需要对 3 个向量进行归一化

    A = A / |A|
    X = X / |X|
    Y = Y / |Y|
    

    通过做找到两个角度

    acos(A dot X)
    acos(A dot Y)
    

    ===

    我不明白失去精度的意义。您只是在比较,而不是以任何方式修改点的坐标...

    【讨论】:

    • 您假设 A 和 X 的大小为 1(或互为倒数)。 A 和 Y 也是如此。
    【解决方案3】:

    您可能想查看Rational Trigonometry。距离和角度的概念换成了四边形和散布,不涉及sqrtcos。请参阅该网页的底部以了解如何计算两行之间的分布。该主题有自己的网站,甚至还有youtube channel

    【讨论】:

      【解决方案4】:

      为了保持准确性,我宁愿不使用 cos 或 sqrt。

      这毫无意义。

      但这对我来说似乎太复杂了。

      这对我来说似乎完全错误。

      取两个向量之间的差并查看分量的符号。

      您需要注意的是“更小”的含义。如前所述,这个想法并不是很精确。例如,如果一个点 A 在象限 4(x 分量 > 0 和 y 分量 0 和 y 分量 > 0),那么 "更小”是什么意思?矢量从原点到 A 的角度在零和 π/2 之间;矢量从原点到 B 的角度在 3π/4 和 2π 之间。哪个“更小”?

      【讨论】:

      • 这是一个很好的观点。角度∢ABX 定义为BX 的角度,当AB 被转换为位于开放段(-∞,0] 上时。直观地说,我是指访问顶点@ 后左转时的角度ABX 987654325@.
      • Cos 是一个近似值,所以是的,除了这些操作的高成本之外,还损失了一些准确性。此外,他只需要单调函数而不是值本身。
      【解决方案5】:

      我不确定您是否可以在不使用 sqrt 的情况下逃脱。 简单:

      AB = A-B/|A-B|
      XB = X-B/|X-B|
      YB = Y-B/|Y-B|
      
      if(dot(XB,AB) > dot (YB,AB)){
       //<ABY is grater
      }
      else
      {
      ...
      }
      

      【讨论】:

      • 我在问题中描述了一种不使用平方根的方法。我很高兴听到为什么我的方法不起作用。
      【解决方案6】:

      使用余弦定律:a**2 + b**2 - 2*a*b*cos(phi) = c**2

      其中 a = |ax|,b =|bx| (|by|), c=|ab| (|ay|) 和 phi 是你的角度 ABX (ABY)

      【讨论】:

      • 不使用 sqrt 如何获得这些距离?
      • 必须放弃“无平方根”的想法。
      • 你不需要 sqrt。您将 cos(phi1) 与 cos(phi2) 进行比较。两者中越大的角度越大。
      • 真的吗?您如何处理 x = 0 处的不连续性?
      • 您将需要 sqrt 来计算 2*a*b 术语(您需要这样做来解决 cos(phi))。此外,cos(phi1)cos(phi2) 中较大的一个将对应较小的角度。
      猜你喜欢
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 2018-02-28
      相关资源
      最近更新 更多