我的问题如下:
假设我处于 (x, y, z) 位置,并且有几个点 (xn, yn, zn),并且根据我的 View 方向,假设我有垂直、水平和滚动的角度值,我希望我的 HUD 能够识别所述点(如果它们在我的视角中),并在任何角度发生变化时四处移动。基本上将其转换为屏幕上的 (x, y) 坐标。
就像以下游戏中任务点的行为:https://www.youtube.com/watch?v=I_LlEC-xB50
我该怎么做?
编辑: 我使用以下方法获取坐标:
def convert_to_xyz(point):
# Lat / Lon / Alt -> point[0] / point[1] / point[2]
# Note: point[2] = earth circumference + altitude
point[2] += _earth_radius
x = math.cos(point[0]) * math.cos(point[1]) * point[2]
y = math.cos(point[0]) * math.sin(point[1]) * point[2]
z = math.sin(point[0]) * point[2] # z is 'up'
return numpy.array([x, y, z])
获取相机矩阵:
def get_camera_matrix(fovx, fovy, height, width):
# FOVX is the horizontal FOV angle of the camera
# FOVY is the vertical FOV angle of the camera
x = width / 2
y = height / 2
fx = x / math.tan(fovx)
fy = y / math.tan(fovy)
return np.array([[fx, 0, x],
[0, fy, y],
[0, 0, 1]])
转换到相机空间:
def transform_to_camera_space(point, camera_matrix):
return np.dot(point, camera_matrix)
然后我使用@spug 答案,得到如下值:
array([ 133.99847154, 399.15007301])
最佳答案
第 1 步:
通过将点乘以相机矩阵,将点从世界空间变换到相机空间。您应该阅读有关构建此内容的内容 - 有无数的网络资源。在(俯仰、偏航、横滚)坐标中,旋转必须按照横滚 -> 俯仰 -> 偏航 的顺序进行,对应于:
绕 X 轴旋转角度
roll
-> 矩阵 R绕 Y 轴旋转角度
pitch
-> 矩阵 P绕 Z 轴旋转角度
yaw
-> 矩阵 Y
相机矩阵的旋转部分由 (YPR)T 给出,按乘法顺序强>。本页给出了 XYZ 旋转矩阵:https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations .
相机空间中的点由 q = transpose(YPR) * (p - c)
给出,其中 p = (xn, yn, zn)
是世界空间中的点,c = (x, y, z)
是您的相机位置。另一种方法是构造一个 4x4 矩阵并用 -(YPR)*c
填充第 4 列 - 再次可在互联网上找到。
此时,如果点 q
的 X 值低于某个限制(称为近裁剪平面 - 将其设置为某个正值),则丢弃该点。这可确保不会显示相机后面的点。
第 2 步:
下图说明了透视投影背后的过程:
- Theta 是 FOV 的一半
- p 是点的深度值 = 相机坐标系中的 X 坐标)
- s 是相机框架中的 Y 坐标
- X 是屏幕坐标
Y 也类似:
- t 是相机框架中的 Z 坐标
- A 是纵横比(高度/宽度)
关于python - 根据相机的方向在 HUD 上移动 3d 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44762960/