根据相机的方向在 HUD 上移动 3d 点

Have a 3d point move on HUD depending the direction of the camera

我的问题如下:

假设我在 (x, y, z) 位置并且我有几个点 (xn, yn, zn) 并且取决于我的视角方向,假设我有垂直、水平和滚动的角度值,我希望我的 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]])

转换为相机 space:

def transform_to_camera_space(point, camera_matrix):
  return np.dot(point, camera_matrix)

然后我使用@spug 答案,我得到的值如下:

array([ 133.99847154,  399.15007301])

第 1 步:

将点从worldspace转换为cameraspace,方法是将其乘以相机矩阵.您应该仔细阅读有关构建它的内容 - 有无数的网络资源。在 (pitch, yaw, roll) 坐标中,旋转必须按照 roll -> pitch -> yaw 的顺序发生,对应于:

  1. 绕X轴旋转过角度roll -> 矩阵R

  2. 绕Y轴旋转过角度pitch -> 矩阵P

  3. 绕Z轴旋转过角度yaw -> 矩阵Y

相机矩阵的旋转部分由(YPR)T给出, 乘法顺序。本页给出了 XYZ 旋转矩阵:https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations.

相机 space 中的点由 q = transpose(YPR) * (p - c) 给出,其中 p = (xn, yn, zn) 是世界 space 中的点,c = (x, y, z) 是您的相机位置.另一种方法是构建一个 4x4 矩阵并用 -(YPR)*c 填充第 4 列 - 同样,可在互联网上获得。

此时,如果点 q 的 X 值低于某个限制(称为近裁剪平面 - 将其设置为某个正值),则丢弃该点。这样可以确保不显示相机后面的点。


第 2 步:

下图说明了透视投影背后的过程:

  • Theta 是 FOV 的一半
  • p 是点的深度值 = 相机框架中的 X 坐标)
  • s 是相机坐标系中的 Y 坐标
  • X 是屏幕坐标

同样适用于 Y:

  • t 是相机坐标系中的 Z 坐标
  • A 是您的纵横比(高度/宽度)