C++ 为什么acos()会导致;南区(工业区)“;当使用点积的结果时?
我对这个问题很困惑。我正在运行的代码是:C++ 为什么acos()会导致;南区(工业区)“;当使用点积的结果时?,c++,armadillo,math.h,C++,Armadillo,Math.h,我对这个问题很困惑。我正在运行的代码是: double dotProduct = dot(A, B); std::cout << dotProduct << std::endl; theta = acos(dotProduct); std::cout << theta << std::endl; 然而,以下工作: double dotProduct = dot(A, B); std::cout << dotProduct <&l
double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos(dotProduct);
std::cout << theta << std::endl;
然而,以下工作:
double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
dotProduct = -1;
theta = acos(dotProduct);
此外,如果我将dotProduct强制转换为浮点,acos()会正确输出角度:
double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos((float) dotProduct);
对于dot()函数,我使用Armadillo库。我不明白的是,当我设置dotProduct=-1时,为什么acos()应该工作,而当它由dot()函数输出时,acos()将不工作。我做错了什么?我假设
A
和B
是标准化向量,因此您希望点(A,B)
介于-1
和1
之间。对于浮点数学,这不一定是真的<代码>|点(A,B)可以略大于1
。我敢打赌,如果您以更高的精度打印它,您将看到您的值略小于-1
因此,您需要将点(A,B)
夹在-1
和1
之间。如果输入介于-1
和1
之间,则最好只调用acos()
:
double safe_acos(double value) {
if (value<=-1.0) {
return <pi>;
} else if (value>=1.0) {
return 0;
} else {
return acos(value);
}
}
double-safe\u-acos(双值){
如果(值=1.0){
返回0;
}否则{
返回acos(值);
}
}
这可能会稍微快一点,因为您可以避免调用acos()
来获取超出范围的值
注意:如果你做3D数学,你很有可能完全避免调用
acos()
。使用三角恒等式,通常我们可以用更快、更精确的解来代替它。很可能dot_product
返回的值略大于1,并且在输出流中插入double
的默认格式不能完全显示值。在double
之前插入std::setprecision(99)
应该会显示它。将其转换为float
将舍入到最近的可表示的float
,因为该值非常接近于1,所以正好是1。如果@ericpostischil是正确的,则可以使用dotProduct=std::clamp(dotProduct,-1,1.)代码>(注意,我的“略大于一”应该是“略大于一的大小”。例如。,−1.00001…)
double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos((float) dotProduct);
-1
ANGLE: 3.14159
double safe_acos(double value) {
if (value<=-1.0) {
return <pi>;
} else if (value>=1.0) {
return 0;
} else {
return acos(value);
}
}