0

去年我在一所学校的 C++ 游戏开发课上学到,要找到两个向量之间的角度,可以使用以下方法:

vec2_t 定义为:typedef float vec2_t[2]; vec[0] = x 和 vec[1] = y

float VectorAngle(vec2_t a, vec2_t b)
{
    vec2_t vUp;
    vec2_t vRight;
    vec2_t vDir;
    float dot, side, angle;

    VectorCopy(vUp, a);
    VectorNormalize(vUp);

    VectorInit(vRight, -vUp[1], vUp[0]);

    VectorCopy(vDir, b);
    VectorNormalize(vDir);

    dot = VectorDot(vUp, vDir);
    side = VectorDot(vRight, vDir);
    angle = acosf(dot);

    if(side < 0.0f)
        angle *= -1.0f;

    return angle;
}

然后就在昨天,在寻找其他解决方案时,我发现您可以改用此方法:

float VectorAngle(vec2_t a, vec2_t b)
{
    return atan2f(b[1]-a[1], b[0]-a[0]);
}

这似乎更容易实现......我的问题是,当第二种方法更简单时,为什么一种方法会优于第二种方法?

编辑:只是为了确保:如果向量 a 是 [100, 100] 并且向量 b 是 [300, 300] 那么方法 2 返回 0.78539819 弧度,这是正确的吗?

4

4 回答 4

3

我觉得有用的一种方法:

        // cross product
        double y = (v1[0] * v2[1]) - (v2[0] * v1[1]);

        // dot product
        double x = (v1[0] * v2[0]) + (v1[1] * v2[1]);

        return atan2(y, x);
于 2012-12-21T04:33:19.100 回答
2

第二种方法计算 b 和 a (ba) 的几何差向量,并返回这个差和 X 轴之间的角度,显然这个角度通常不等于 a 和 b 之间的角度。

于 2012-12-21T05:53:56.677 回答
1

acosf源代码与atanf2f源代码进行比较,以了解实现的差异。后者使用可能对某些系统不可行的表。

于 2012-12-21T04:30:35.583 回答
0

您可以使用复数进行二维矢量计算。复数的乘法可以看作是正旋转,除法是负旋转。我们想使用除法,因为它的作用是从另一个角度减去一个角度:

#include <complex>

int main() {
    using std::complex;
    using std::arg;

    complex<double> a, b;

    double angle = arg(a/b);

    return 0;
}
于 2012-12-21T08:49:53.197 回答