我需要制作一个函数来计算让NPC看到玩家中心所需的度数。但是,我无法找到有关我需要的3个维度的任何结果。只有二维方程。我正在用C ++编程。
的信息:
数据类型:Float。
垂直轴:90正向上看,-90正向下看,0正向前看。
水平轴:0到360之间的正值,北为0,东为90,南180,西270。
答案 0 :(得分:1)
请参阅维基百科的these transformation equations。但请注意,因为您希望在xy平面上“仰角”或“垂直轴”为零,所以您需要在“如果θ测量参考平面的高度而不是从天顶倾斜”之后进行更改。/ p>
首先,找到从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代替欧拉角。无论如何你都要创建矩阵,所以为什么不使用它......
创建/使用NPC转换矩阵M
我的赌注是你在网格附近得到它并且你正在使用它进行渲染。如果您使用欧拉角,您正在进行一组旋转和平移,结果是M
。
将玩家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))
按角度旋转或构建新的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')
但要将其转换为欧拉角是另一个故事......
使用变换矩阵,您可以轻松制作酷炫的东西,如相机跟踪,物体坐标系统之间的简单计算,简单的物理运动模拟等等。