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

时间:2017-06-26 15:16:42

标签: python 3d camera 2d hud

我的问题如下:

想象一下我在(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]])

转换为相机空间:

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

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

array([ 133.99847154,  399.15007301])

1 个答案:

答案 0 :(得分:1)

第1步:

将点从 world 空间转换为 camera 空间,将其乘以相机矩阵。你应该阅读构建它 - 有无数的网络资源。在(俯仰,偏航,滚动)坐标中,旋转必须按照 roll - >的顺序发生。音高 - >偏航,对应于:

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

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

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

  4. 相机矩阵的旋转部分由( 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值低于某个极限(称为近剪裁平面 - 将其设置为某个正值),则丢弃该点<html> <script> var original_Top = -1, original_Left = -1; function rotatedPosition(pLeft, pTop, oLeft, oTop, angle){ original_Top = pTop; original_Left = pLeft; // 1 let x = pLeft - oLeft; let y = pTop - oTop; // 2 let xRot = x * Math.cos(angle) - y * Math.sin(angle); let yRot = x * Math.sin(angle) + y * Math.cos(angle); // 3 let pLeftRot = xRot + oLeft; let pTopRot = yRot + oTop return {left: pLeftRot, top: pTopRot}; } </script> <body> <div id="test" style="width:50px;height:50px;background-color:yellow"> </div> </body> </html> 。这样可以确保不显示相机后面的点。

    第2步:

    下面是一个说明透视投影背后的过程的图表:

    enter image description here

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

    enter image description here

    同样的Y:

    enter image description here

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