【问题标题】:Calculating actual angle between two vectors in Unity3D在Unity3D中计算两个向量之间的实际角度
【发布时间】:2018-02-12 00:41:40
【问题描述】:

有没有一种方法可以计算 Unity 中两个 3D 矢量之间的实际角度? Vector3.Angle 给出两个向量之间的最短角度。我想知道以顺时针方式计算的实际角度。

【问题讨论】:

  • 最短角度是什么意思?两个向量之间只有一个角度。角度通常通过(概念上)从弧中的第一个向量向第二个向量移动来计算。
  • 我不希望通过将第一个向量顺时针或逆时针方向移向向量来计算角度。在 Vector3.Angle 的实现中,如果向量 2 从向量 1 顺时针旋转 90 度,或者即使是 270 度,我得到 90 度。我希望它返回 270 度。
  • 两秒前我刚刚发布(并删除)的答案显然是错误的,但我认为您最终肯定会使用这两个向量的点积。
  • 顺便问一下,“顺时针”到底是什么意思?您想从哪一点开始查看这些向量并确定它们是顺时针还是逆时针?
  • 如果从上述空间点的角度来看,这些向量恰好投影到一条线上呢?例如,如果您想通过从 (0,+9001,0) 的点看来确定向量的“顺时针方向”,那么在 X-Y 平面上呢?

标签: vector unity3d


【解决方案1】:

这应该是你需要的。 ab 是您要计算角度的向量,n 将是您的平面的法线,以确定您所说的“顺时针/逆时针”

float SignedAngleBetween(Vector3 a, Vector3 b, Vector3 n){
    // angle in [0,180]
    float angle = Vector3.Angle(a,b);
    float sign = Mathf.Sign(Vector3.Dot(n,Vector3.Cross(a,b)));

    // angle in [-179,180]
    float signed_angle = angle * sign;

    // angle in [0,360] (not used but included here for completeness)
    //float angle360 =  (signed_angle + 180) % 360;

    return signed_angle;
}

为简单起见,我重用Vector3.Angle,然后根据平面法线nab 的叉积(垂直向量)之间的角度大小计算符号。

【讨论】:

  • 能否提供该方法的使用示例?
  • Jedrak 的回答很好,但是如果你想得到 [0, 360) 范围内的角度,你必须修改 angle360 公式(写 360 而不是 180): float angle360 = (signed_angle + 360) % 360;
  • 您能解释一下这背后的数学原理吗?特别是float sign = Mathf.Sign(Vector3.Dot(n,Vector3.Cross(a,b)));
  • @UgoHed 2 个向量 ab 定义了一个平面,但隐含的第三个向量,前 2 个的叉积,定义了平面的法线。 ab 之间的任何角度都围绕该第三轴旋转。所以问题是我们以哪种方式旋转?两个向量之间的角度始终为正角度。 Vector3.Angle(a,b) == Vector3.Angle(b,a)。为了找到旋转方向,我们使用您确定的线,它基本上只是将用户定义的旋转轴n 与隐式轴进行比较。如果匹配,则符号为正,否则,符号为负。
【解决方案2】:

如果您只使用加法和减法,这很容易。看看这个:

/Degrees
  float signedAngleBetween (Vector3 a, Vector3 b, bool clockwise) {
  float angle = Vector3.angle(a, b);

  //clockwise
  if( Mathf.Sign(angle) == -1 && clockwise )
    angle = 360 + angle;

  //counter clockwise
  else if( Mathf.Sign(angle) == 1 && !clockwise)
    angle = - angle;
  return angle;
}

这就是我的意思: 如果我们是顺时针方向并且角度是负数,例如-170 要使其达到 180,请使用此等式。 "180-|角度|+180" 你已经知道角度是负的,所以,使用“180-(-角度)+180”并添加180的“360 +角度”。 那么如果是顺时针方向,CONTINUE,如果是逆时针方向,则将角度设为负值,这是因为360度角的另一部分(即360度+角度的补码)是“360 - (360 + 角度)”或 “360 - 360 - 角度”或“(360 - 360) - 角度”,同样,OR“- 角度”。所以我们开始......你完成的角度。

【讨论】:

    【解决方案3】:

    尝试使用Vector3.Angle(targetDir, forward);

    既然你想要它们之间的最短角度,那么如果返回的值大于 180 度,只需用这个值减去 360 度。

    查看http://answers.unity3d.com/questions/317648/angle-between-two-vectors.html

    【讨论】:

    • 正如上面评论中提到的,我不是在寻找最短的角度,而是考虑到向量顺序的角度。
    • 好的,这是一个想法:检查向量在哪个象限。例如,如果 x 分量为正而 y 分量为负,那么它在第 4 象限。用你的 2 个向量来做,你会知道它们相对于彼此的方向。现在,如果两个向量恰好在同一个象限内,只需计算每个向量与另一个向量之间的角度,比如位于象限 1 和 4 之间的向量。从这些角度,您应该能够确定它们的相对方向.
    • 我也试过了。这部分有效,但如果我尝试比较向量之间的角度,则在象限内会出现同样的问题。对最后一步稍作改动虽然给了我们一个解决方案,但仍然不方便。您可以比较两个象限内两个向量的 x 分量,而不是检查向量与该象限中的任意向量之间的角度。您仍然需要确保两个向量都在同一个象限中,否则它将无法正常工作。
    • 如果您查看文档,Vector3.Angle 会说:“返回的角度始终是锐角......永远不会大于 180 度”。因此,此答案不仅是在回答 OP 没有提出的问题,而且还包含误导性或错误信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2017-08-22
    相关资源
    最近更新 更多