代码之家  ›  专栏  ›  技术社区  ›  anonymous coward

确定一个角度与另一个角度的夹角是否在X度以内

  •  8
  • anonymous coward  · 技术社区  · 16 年前

    我需要一个算法来计算一个角度与另一个角度的夹角是否在一定的角度范围内。

    我的第一个想法是 (a-x < b) && (a+x > b) ,但当它必须处理从-179到180的角度时,它就失败了。

    在上图中,该区域(绿色)的角度必须介于正负侧之间的包裹之间。如何确定角度(红线)是否落在该区域内?

    5 回复  |  直到 9 年前
        1
  •  7
  •   Graviton    16 年前

    试试这个公式:

    360-(|a-b|)%360<x || (|a-b|)%360<x
    

    in PHP :

    <?php
    
    $b = 10;
    $angle1 = -179;
    $angle2 = 180;
    
    $diff = $angle1 - $angle2;
    if(abs($diff % 360) <= $b || (360-abs($diff % 360))<=$b) {
      echo "yes";
    } else {
      echo "no";
    }
    
    ?>
    
        2
  •  3
  •   cletus    16 年前

    正如马塞尔正确地指出的那样,负数的模是潜在的问题。另外,355度和5度之间有什么区别?它可能被计算为350度,但10度可能是人们所期望的。我们作出以下假设:

    1. 0 <= diff <= 180 ;
    2. 我们以学位为单位工作。如果是弧度,则用360代替 2*PI
    3. 角度可以是正角度,也可以是负角度,但不能超出范围 -360 < x < 360 其中x是一个输入角度,并且

    输入:角度a和b。因此,算法很简单:

    1. 0 <= x < 360 ;
    2. 计算两个法线角度之间的最短角度。

    对于第一步,要将角度转换为所需范围,有两种可能性:

    • x >= 0
    • x < 0 :正常=(-x/360+1)*360+x

    第二种方法旨在消除负模运算解释差异上的任何歧义。因此,给出一个x=-400的工作示例:

      -x / 360 + 1
    = -(-400) / 360 + 1
    = 400 / 360 + 1
    = 1 + 1
    = 2
    

    然后

    normal = 2 * 360 + (-400)
           = 320
    

    因此,对于输入10和-400,法向角为10和320。

    normal1 = min(normal(a), normal(b))
    normal2 = max(normal(a), normal(b))
    angle1 = normal2 - normal1
    angle2 = 360 + normal1 - normal2
    

    因此,就我们的例子而言:

    normal1 = min(320, 10) = 10
    normal2 = max(320, 10) = 320
    angle1 = normal2 - normal1 = 320 - 10 = 310
    angle2 = 360 + normal1 - normal2 = 360 + 10 - 320 = 50
    

    你会注意到的 normal1 + normal2 = 360 (如果你愿意,你甚至可以证明这一点)。

    最后:

    diff = min(normal1, normal2)
    

    在我们的情况下是50。

        3
  •  2
  •   peejaybee    16 年前

    您也可以使用dot产品:

    cos(a)*cos(b) + sin(a)*sin(b) >= cos(x)
    
        4
  •  1
  •   Steve Weller    16 年前

    对于半径为1的情况,直线端点之间的距离为2sin((a-b/2)。因此,由于您只对比较感兴趣,所以请扔掉2,并将sin(x/2)与sin((a-b)/2)进行比较。trig函数负责所有的包装。

        5
  •  0
  •   Pedro Soares    12 年前

    C++实现:

    float diff = fabsf(angle1 - angle2);
    bool isInRange = fmodf(diff, 360.0f) <= ANGLE_RANGE ||
                     360.0f - fmodf(diff, 360.0f) <= ANGLE_RANGE;
    
    推荐文章