C++ 如何有效地计算两点之间的角度?

C++ 如何有效地计算两点之间的角度?,c++,math,optimization,game-physics,C++,Math,Optimization,Game Physics,我试图在我的实验中优化模拟功能,这样我就可以一次运行更多人工大脑控制的代理。我分析了我的代码,发现现在代码中的最大瓶颈是计算每个代理到每个代理的相对角度,即O(n2),减去我做的一些小优化。以下是我当前用于计算角度的代码片段: [C++] double calcAngle(double fromX, double fromY, double fromAngle, double toX, double toY) { double d = 0.0; double Ux = 0.0,

我试图在我的实验中优化模拟功能,这样我就可以一次运行更多人工大脑控制的代理。我分析了我的代码,发现现在代码中的最大瓶颈是计算每个代理到每个代理的相对角度,即O(n2),减去我做的一些小优化。以下是我当前用于计算角度的代码片段:

[C++]
double calcAngle(double fromX, double fromY, double fromAngle, double toX, double toY)
{
    double d = 0.0;
    double Ux = 0.0, Uy = 0.0, Vx = 0.0, Vy = 0.0;

    d = sqrt( calcDistanceSquared(fromX, fromY, toX, toY) );

    Ux = (toX - fromX) / d;

    Uy = (toY - fromY) / d;

    Vx = cos(fromAngle * (cPI / 180.0));
    Vy = sin(fromAngle * (cPI / 180.0));

    return atan2(((Ux * Vy) - (Uy * Vx)), ((Ux * Vx) + (Uy * Vy))) * 180.0 / cPI;
}
我有两个2D点(x1,y1)和(x2,y2)以及“起始”点(xa)的面。我想计算代理x需要转向(相对于其当前面)面对代理y的角度


根据profiler,最昂贵的部件是atan2。我在谷歌上搜索了几个小时,上面的解决方案是我能找到的最好的解决方案。有人知道一种更有效的方法来计算两点之间的角度吗?我愿意牺牲一点精度(+/-1-2度)来提高速度,如果这对速度有影响的话。

我认为这更像是一个数学问题:

试一试


abs(arctan((y1-yfrom)/(x1-xfrom))-arctan(1/(y2-yfrom2)/(x2-xfrom2))

如评论中所述,可能有一些高级方法可以降低计算负载

但对于手头的问题,您可以使用:

如果
a
b
是向量,
表示“点积”,而
| | |
表示“向量大小”

基本上,这将用{
sqrt
cos
sin
atan2
}替换您的{
sqrt
aco
}

我还建议在所有内部计算中坚持弧度,仅在人类可读的I/O中转换为度数和度数。

使用这两个向量的组合,最坏的情况下,您需要做反余弦:

A=朝向方向。B=代理Y从代理X的方向


计算点是简单的乘法和加法。由此得到角的余弦

对于初学者,您应该意识到有两种简化方法可以稍微减少计算量:

  • 你不需要计算从一个代理到它自身的角度
  • 如果你有从代理i到代理j的角度,你已经知道了从代理j到代理i的角度 我必须问:“特工我面对特工j”是什么意思?如果两个曲面正对着对方,是否需要进行计算?你对“直视对方”有什么容忍度


    如果你不再把注意力集中在数学上,更全面地描述这个问题,那么建议该怎么做就更容易了。

    你的评论说明了很多:“我正在为每个代理模拟一个180度的额叶视网膜,所以我需要这个角度。”。不,你没有。您只需要知道位置向量和视觉向量之间的角度是大于还是小于90度


    这很简单:如果A和B之间的角度小于90度,则点积
    A·B
    大于0;如果角度正好是90度,请注意,结果将以弧度为单位,您必须将其除以π,然后将其乘以180,才能得到角度不是角度,而x1、x2、y1、y2是坐标?不确定这里减去了什么。xfrom和yfrom都是直线起点的坐标。。。XOX相当于他的“XA”:“点(XA)”的“有一个稳定的C++库,自动处理这种游戏逻辑,一个La XNA游戏工作室的C语言库?”兰迪奥森:这恐怕超出了我的专业领域。如果你知道如何计算点积和量值,为什么需要一个库?它几乎不值得一个库。游戏机制不仅仅是向量的点积和大小。你不需要
    sqrt
    我想:(a.b/| | | a | | | | b | |)b=cosθ=(1+cos2θ)/2No,对不起。浮点非线性数学是昂贵的。“我的代码现在最大的瓶颈是计算每个代理到每个代理的相对角度”,你考虑过。。。不这样做?首先,向量数学通常不需要角度;它只使用向量。在需要特定角度的地方,您使用什么函数?第二,为什么需要为每对代理计算这个值?你不是只需要为彼此亲近的人计算吗?有很多方法可以处理对附近实体进行分组的问题。Sinandere cos的查找表如何?Nicol:我在模拟每一个代理的180度额视网膜,所以我需要这个角度,所以我知道视网膜的哪一部分被标记为“有另一个代理”。我已经预先计算了距离,过滤掉了代理可能的视觉距离之外的代理。在决定计算相对角度之前,我还考虑过以某种方式确定代理y是否在代理x之前,但我发现这是一个困难的问题,而不需要直接计算角度的类似成本。@Matthias:我怀疑这会更快(假设我们在这里谈论的是现代桌面/服务器平台)。已经在做1,当然。:-)不幸的是,2并没有消除atan2,因为atan2是相对于“from”代理的正面完成的。我正在为每个代理模拟一个180度的正面视网膜,所以我需要角度,以便我知道视网膜的哪一部分要标记为“有另一个特工在里面。“我已经预先计算了距离,并过滤掉了超出代理可能视觉距离的代理。在决定计算相对角度之前,我也曾考虑过如何计算代理y是否在代理x之前,但我发现这是一个困难的问题,而不需要直接计算角度的类似成本。我最终需要精确的(ish)角度来知道视网膜的哪一部分要标记为“里面有个特工,”但t
    theta = acos ( a . b / ||a|| ||b|| )