如何确定相对方向的360°角度?

时间:2018-02-16 18:16:45

标签: c# math angle direction

我在屏幕上有一个小地图,并且在确定目标相对于相机的角度方面存在问题。

以下是我对相机位置和方向的一些示例的描述:

I describe the problem (hopefully)

  • 黑色三角形代表相机。
  • 黑色箭头定义了它们的前进方向。
  • 蓝色箭头是相机的目标方向(=中间的红点)。
  • 特定相机中的圆圈定义其红点的所需方向。

到目前为止,这是我的代码:

//Anchored position around minimap circle
void CalculateScreenPos(){
    Vector3 dir = transform.position - cam.position; //xz distance 
    dir.y = 0;
    angle = Angle360(cam.forward.normalized, dir.normalized, cam.right);

    Vector2 desiredPosition = new Vector2(
        eX * -Mathf.Cos(angle * Mathf.PI/180f) * dir.z, 
        eY * Mathf.Sin(angle * Mathf.PI/180f) * dir.x
    );

    minimapBlip.anchoredPosition = desiredPosition;
}

public static float Angle360(Vector3 from, Vector3 to, Vector3 right)
{
    float angle = Vector3.Angle(from, to);
    return (Vector3.Angle(right, to) > 90f) ? 360f - angle : angle;
}

但角度似乎不正常,发现它的范围是

  

0°+ cam.eulerXAngles.x至360° - cam.eulerAngles.x

所以当凸轮永远不会看向地面或天空时它会起作用。

如何通过不将角色再次添加/再次添加来消除不需要的x-eulerAngles?

angle -= cam.transform.eulerAngles.x

是一个糟糕的选择,因为当Angle360的结果为360时,它会再次减去,立即导致错误的角度。

圆圈也可以是椭圆体,这就是为什么我将eXeY放在确定椭圆延伸的所需位置的原因。

2 个答案:

答案 0 :(得分:0)

我不知道您使用的数据类型,例如cam.positioncam.heading等,但有一些一般性指导可帮助您调试此问题。

  1. 编写单元测试。准备一些预制数据,包括输入(例如设置cam.position/cam.headingtransform等)和输出(预期角度)。在少数情况下这样做,例如你所展示的所有六个例子。这样可以更轻松地重复测试,并了解哪种情况不起作用 - 您可能会看到一种模式。它还可以通过调试器轻松运行代码。

  2. 将您的职能分解为逻辑工作单元。 Angle360做了什么?我想你明白它应该做什么,但我认为它实际上是两个功能

    1. 获取两个矢量之间的角度(当前方向和目标方向)
    2. 旋转地图(或类似的东西)
  3. 为那些分解的函数编写测试。您只是使用了一些库角度差异功能 - 它是否符合您的预期?

  4. 为变量命名。你有一个名为right的向量 - 这是什么?没有评论。是right是正确的'还是与左边相反?'?为什么Vector3.Angle(right, to),为什么不Vector3.Angle(to, right)

  5. 一般来说,你正在进行一些数学运算并因为你的代码不清楚,事情没有得到很好的命名以及方法不明确而被绊倒。将问题分解成更小的部分,问题将变得明显。

答案 1 :(得分:0)

我解决了它:

angle = Mathf.Atan2(heading.x, heading.z) * Mathf.Rad2Deg-Camera.main.transform.eulerAngles.y;

Vector2 desiredPosition = new Vector2(
    eX * -Mathf.Cos((angle+90) * Mathf.Deg2Rad), 
    eY * Mathf.Sin((angle+90) * Mathf.Deg2Rad)
);

感谢目前为止的帮助和快乐的编码:D