计算两个 3D 向量之间的角度

Calculate Angle between two 3D Vectors

注意:我对矢量数学一无所知,尤其是在 3D 中。

我目前正在编写一些 Javascript 代码来确定被 Leap Motion 控制器捕获的手指是否伸展(即完全伸直)。

Leap Motion 为我们提供了一个 API,它为我们提供了手、手指和骨骼的对象。特别是骨骼有几个属性,例如位置向量、方向向量等,参见here for the Documentation

我的想法是取 Distal Phalang(指尖)和 Proximal Phalang(手指的第一根骨头),通过获取骨头的两个方向向量的点积来计算它们之间的角度,然后决定它是否直。像这样,本质上是:

var a = hand.indexFinger.distal.direction();
var b = hand.indexFinger.proximal.direction();
var dot = Leap.vec3.dot(a,b);
var degree = Math.acos(dot)*180/Math.PI;

这里的问题是这些值不可靠,尤其是当其他手指四处移动时。似乎当其他手指改变方向时,骨骼的方向向量也会改变 (???)。

例如,当我所有的手指都伸出时,度数的值大致为0,在-5和5之间波动。当我握拳时,该值猛增到10、15、20。记录这些值Vectors 的方向表明它们确实发生了变化,但这有什么意义呢?手指没有移动,所以它的方向应该保持不变。

对于拇指来说更糟的是,那里的值根本不相加。伸出的拇指可以得到类似于IndexFinger的值,但是向上或向下旋转拇指有60度范围内的变化!

我试过使用位置值来代替,这给了我 NaN 结果,因为这些值似乎太大了。

所以,我的问题是:如何可靠地计算两个向量之间的角度?我在这里错过了什么?

正确的公式是

cos(angle) = dot(a,b)/(norm(a)*norm(b))

其中 norm 是欧氏范数或长度。

你应该得到了一个错误的结果,但是a和b的长度应该是常数,所以结果应该一直是错误的......

如果这些向量被归一化,则点积是向量之间夹角的余弦值。因此,请确保在计算点积之前对 a 和 b 进行归一化