当使用点积的结果时,为什么acos()导致“nan(ind)”?

问题描述 投票:2回答:1

我对这个问题非常困惑。我正在运行的代码是:

double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos(dotProduct);
std::cout << theta << std::endl;

其输出是

-1
ANGLE: -nan(ind)

但是,以下工作:

double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
dotProduct = -1;
theta = acos(dotProduct);

给出输出:

-1
ANGLE: 3.14159

另外,如果我将dotProduct转换为float,acos()会正确输出角度:

double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos((float) dotProduct);

也导致输出

-1
ANGLE: 3.14159

对于dot()函数,我使用的是Armadillo库。我不明白为什么当我设置dotProduct = -1时acos()应该工作,但是当dot()函数输出时它不会。我究竟做错了什么?

c++ armadillo math.h
1个回答
2
投票

我认为AB是归一化的向量,因此你期望dot(A, B)介于-11之间。对于浮点数学,这不一定是真的。 |dot(A, B)|可能比1略大。我打赌,如果你用更高的精度打印它,你会发现你的值略小于-1

所以,你需要在dot(A, B)-1之间夹住1。或者更好的是,如果输入在acos()-1之间,则仅调用1

double safe_acos(double value) {
    if (value<=-1.0) {
        return <pi>;
    } else if (value>=1.0) {
        return 0;
    } else {
        return acos(value);
    }
}

这可能会稍微快一些,因为你避免调用acos()来获取越界值。

注意:如果你进行3D数学运算,你很有可能完全避免调用acos()。使用三角恒等式,通常我们可以用更快,更准确的解决方案替换它。

© www.soinside.com 2019 - 2024. All rights reserved.