我在游戏中有两个向量 . 一个向量是玩家,一个向量是一个对象 . 我还有一个向量,指定玩家面对的方向 . 方向矢量没有z部分 . 这个点的大小为1,位于原点附近 .
我想计算士兵当前面对的方向和物体之间的角度,所以我可以正确地平移一些音频(仅限立体声) .
下图描述了我的问题 . 我想计算两条虚线之间的角度 . 一条虚线连接玩家和物体,另一条线代表玩家从玩家所处的方向所朝向的方向 .
目前,我正在这样做(假设玩家,物体和方向都是3点,x,y和z的向量):
Vector3d v1 = direction;
Vector3d v2 = object - player;
v1.normalise();
v2.normalise();
float angle = acos(dotProduct(v1, v2));
但它似乎给我不正确的结果 . 有什么建议?
代码测试:
Vector3d soldier = Vector3d(1.f, 1.f, 0.f);
Vector3d object = Vector3d(1.f, -1.f, 0.f);
Vector3d dir = Vector3d(1.f, 0.f, 0.f);
Vector3d v1 = dir;
Vector3d v2 = object - soldier;
long steps = 360;
for (long step = 0; step < steps; step++) {
float rad = (float)step * (M_PI / 180.f);
v1.x = cosf(rad);
v1.y = sinf(rad);
v1.normalise();
float dx = dotProduct(v2, v1);
float dy = dotProduct(v2, soldier);
float vangle = atan2(dx, dy);
}
2 回答
在计算角度增量时,你总是使用
atan2
,然后进行标准化 . 原因是例如acos
是域-1 ... 1的函数;如果输入绝对值(因为近似值)大于1,即使很明显在这种情况下你会喜欢0或PI的角度,函数也会失败 . 此外acos
无法测量全范围-PI..PI,您需要使用显式符号测试来查找正确的象限 .相反
atan2
只有奇点位于(0, 0)
(当然,计算角度没有意义),其codomain是完整的圆-PI ... PI .这是C中的一个例子
在一般的三维方向的情况下,您需要 two 正交方向,例如鼻子指向的向量和右耳所在的向量 . 在这种情况下,公式稍微复杂一些,但如果你有点产品,则更简单:
在3D空间中,您还需要计算the axis: