以下是代码:
double angle( double *vec1 , double *vec2 ){
return acos( ( *vec1 * *vec2 + *(vec1+1) * *(vec2+1) + *(vec1+2) * *(vec2+2) ) / ( sqrt( pow( *vec1 , 2 ) + pow( *(vec1+1) , 2 ) + pow( *(vec1+2) , 2 ) ) * sqrt( pow( *vec2 , 2 ) + pow( *(vec2+1) , 2 ) + pow( *(vec2+2) , 2 ) ) ) );
}
输入的矢量:<1,1,1> , <2,2,2>
返回angle: -1.#IND00
你能告诉我,有什么不对吗?
这是代码“可读”:
arcCos[ (x1*x2 + y1*y2 + z1*z2) / sqrt(x1^2 + y1^2 + z1^2) * sqrt(x2^2 + y2^2 + z2^2) ]
答案 0 :(得分:2)
你的计算结果应该计算出acos(1),你给出的数字应该是0.然而,1是在acos(x)允许范围的最顶部给出真实结果,任何更高的东西都会很复杂(或者在大多数情况下都会产生某种错误)。
我的猜测是你得到的浮点数略大于引起问题的浮点数。原因是每个人的朋友浮点舍入错误。
当使用您的计算方法时,您将最终得到的股息是两个平方根的乘积。在这种情况下,平方根将是sqrt(3)和sqrt(12)。当相乘时,它们将给出一个整数--6。但是,如果这两个数字都略微向下舍入以使它们适合浮点,那么当它们相乘时它们可能会略微小于6.然后最终得到6(在顶部)由略小于6的东西划分,这会给你略大于一的东西。
尝试降低此风险的一种方法是将计算更改为:
sqrt((x1^2 + y1^2 + z1^2) * (x2^2 + y2^2 + z2^2))
这导致sqrt只在产品上进行一次,更有可能产生正确的结果。
答案 1 :(得分:1)
好的......在这里......问题是由于数学: - )
首先我重构了你的代码:
double angle( double *vec1 , double *vec2 ){
// sqlen = 6
double sqlen = vec1[0] * vec2[0] + vec1[1] * vec2[1] + vec1[2] * vec2[2];
// sqpow1 = 3
double sqpow1 = pow( vec1[0] , 2 ) + pow( vec1[1] , 2 ) + pow( vec1[2] , 2 );
// sqpow2 = 12
double sqpow2 = pow( vec2[0] , 2 ) + pow( vec2[1] , 2 ) + pow( vec2[2] , 2 );
// 6/(sqrt(3)*sqrt(12)) = 1
return acos( sqlen / ( sqrt(sqpow1) * sqrt(sqpow2) ) );
}
这应该返回'0',因为acos(1)明确定义为0.; - )