让角色看看球员?

时间:2017-09-24 23:55:04

标签: c++ math

我需要制作一个函数来计算让NPC看到玩家中心所需的度数。但是,我无法找到有关我需要的3个维度的任何结果。只有二​​维方程。我正在用C ++编程。

的信息:

数据类型:Float。

垂直轴:90正向上看,-90正向下看,0正向前看。

水平轴:0到360之间的正值,北为0,东为90,南180,西270。

3 个答案:

答案 0 :(得分:1)

请参阅维基百科的these transformation equations。但请注意,因为您希望在xy平面上“仰角”或“垂直轴”为零,所以您需要在“如果θ测量参考平面的高度而不是从天顶倾斜”之后进行更改。

首先,找到从NPC到玩家的向量,以获取值x, y, z,其中x对东方为正,y对北方为正,{{{ 1}}是正向上的。

然后你有:

z

或者用

替换第一个声明可能会获得更好的精确度
float r = sqrtf(x*x+y*y+z*z);
float theta = asinf(z/r);
float phi = atan2f(x,y);

注意float r = hypotf(hypotf(x,y), z); acosf返回弧度,而不是度数。如果您需要学位,请从:

开始
atan2f

theta *= 180./M_PI; 现在是您的“垂直轴”角度。

此外,维基百科的theta假设正x轴的方位角为零,而正y轴的方位角为pi / 2。由于你想要北方向的方位角为零,东方向的方位角为90,我已经切换到phi = arctan(y/x)(而不是更常见的atan2f(x,y))。此外,atan2f(y,x)会返回-pi到pi的值,但您需要严格的正值。所以:

atan2f

现在if (phi < 0) { phi += 2*M_PI; } phi *= 180./M_PI; 是您想要的“水平轴”角度。

答案 1 :(得分:0)

我不太熟悉涉及旋转和3d环境的数学,但是你不能从坐标到NPC的坐标绘制一条线,反之亦然,并且有一个函数近似于该线的正确旋转直到接受范围+/-?这样做是通过增加和减少垂直和水平值直到它落入范围,这只是导致首先增加或减少的原因,你可以根据NPC的位置状态确定。但我觉得这是非常蹩脚的方式。

答案 2 :(得分:0)

使用4x4 homogenous transform matrices代替欧拉角。无论如何你都要创建矩阵,所以为什么不使用它......

  1. 创建/使用NPC转换矩阵M

    我的赌注是你在网格附近得到它并且你正在使用它进行渲染。如果您使用欧拉角,您正在进行一组旋转和平移,结果是M

  2. 将玩家GCS笛卡尔位置转换为NPC LCS笛卡尔位置

    GCS 表示全局坐标系, LCS 表示本地坐标系。位置是 3D 向量xyz = (x,y,z,1),转换后的位置将是其中之一(取决于您使用的约定)

    xyz'=M*xyz
    xyz'=Inverse(M)*xyz
    xyz'=Transpose(xyz*M)
    xyz'=Transpose(xyz*Inverse(M))
    
  3. 按角度旋转或构建新的NPC矩阵

    您知道 NPC 的旧坐标系,因此您可以从中提取X,Y,Z,O个向量。现在,您只需将作为观察方向的轴(通常为-Z)设置为指向播放器的方向。这很容易

    -Z = normalize( xyz' - (0,0,0) )
     Z = -xyz' / |xyz'|
    

    现在只是利用交叉产品并使其他轴再次垂直于Z:

    X = cross(Y,Z)
    Y = cross(Z,X)
    

    将矢量反馈回 NPC 的矩阵。这种方式移动对象也容易得多。另外,为了锁定侧面旋转,您可以在此之前将其中一个向量设置为Up

    如果您仍想计算旋转,则为:

    ang = acos(dot(Z,-xyz')/(|Z|*|xyz'|))
    axis = cross(Z,-xyz')
    

    但要将其转换为欧拉角是另一个故事......

  4. 使用变换矩阵,您可以轻松制作酷炫的东西,如相机跟踪,物体坐标系统之间的简单计算,简单的物理运动模拟等等。

相关问题