我对这个问题非常困惑。我正在运行的代码是:
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()函数输出时它不会。我究竟做错了什么?
我认为A
和B
是归一化的向量,因此你期望dot(A, B)
介于-1
和1
之间。对于浮点数学,这不一定是真的。 |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()
。使用三角恒等式,通常我们可以用更快,更准确的解决方案替换它。