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

标签 python 3d camera 2d hud

我的问题如下:

假设我处于 (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 步:

通过将点乘以相机矩阵,将点从世界空间变换到相机空间。您应该阅读有关构建此内容的内容 - 有无数的网络资源。在(俯仰、偏航、横滚)坐标中,旋转必须按照横滚 -> 俯仰 -> 偏航 的顺序进行,对应于:

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

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

  3. 绕 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 步:

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

enter image description here

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

enter image description here

Y 也类似:

enter image description here

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

关于python - 根据相机的方向在 HUD 上移动 3d 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44762960/

相关文章:

ios - 使用 isgl3D 未正确进行 3D 对象 (.pod) 中的纹理映射

android - 从 Android 上的相机录制视频到 mp4

python - 设置 DateTimeField 的最小值

java - 检查点是否在三角形内的性能(3D)

python - Binance python websocket - 无响应

math - 平面上的 3d 正交投影

Android 在没有 SurfaceHolder 的情况下拍照

Android:takePicture() 没有声音

python - 在 python 中使用带有条件的服务器端游标读取大量数据

python - 使用 Google API v4 添加带有数据的 Google 表格