将XYZ转换为XY(世界坐标到屏幕坐标)

时间:2017-07-17 22:38:29

标签: math 3d projection

有没有办法转换这些数据:

  • 对象位置是3D点(X,Y,Z),
  • 相机位置是3D点(X,Y,Z),
  • 相机偏航,俯仰,滚动(-180:180,-90:90,0)
  • 视野(-45°:45°)
  • 屏幕宽度&高度

进入屏幕上的2D点(X,Y)?

我正在根据这组确切的数据寻找合适的数学计算。

2 个答案:

答案 0 :(得分:2)

这很困难,但可以为自己做这件事。

有很多图书馆为你做这件事,但如果你自己做的话会更令人满意:

这个问题是可能的,我已经编写了自己的3D引擎来使用javascriptHTML5 Canvas中的对象执行此操作。你可以看到我的代码here并解决我编写的here的3D迷宫游戏,试着去理解下面我要谈的内容...

基本思想是分步进行。首先,您必须忘记摄像机角度(yaw, pitch and roll),因为这些会在稍后出现,只是想象您正在俯视y axis。然后基本思想是使用trig计算俯仰角和偏航到你的物体坐标。通过这个我的意思是想象你正在通过一个信箱看,偏航角将是从中心/中线和你的坐标上下左右坐标左右的角度(正负角度)。采用这些角度,您可以将它们映射到x和y 2D坐标系。

角度的计算是:

pitch = atan((coord.x - cam.x) / (coord.y - cam.y))
yaw   = atan((coord.z - cam.z) / (coord.y - cam.y))

coord.x, coord.y and coord.z是对象的坐标,而凸轮的坐标是cam.x, cam.y and cam.z)。这些计算还假设您正在使用不同轴的笛卡尔坐标系:{{1} },z upy forward

从这里开始,下一步是将3D世界中的这个角度映射到一个可以在2D图形表示中使用的坐标。

要将这些角度映射到屏幕,您需要将它们放大到距中线的距离。这意味着将它们乘以x right。最后,这些距离现在是正的或负的(因为它是与中线的角度),所以要在画布上实际绘制它,你需要将它添加到屏幕宽度的一半。

所以这意味着你的画布坐标将是:

screen width / fov

其中x = width / 2 + (pitch * (width / fov) y = height / 2 + (yaw * (height / fov) width是您屏幕的尺寸,height是相机的fov,fovyaw分别是物体与相机的角度。

您现在已经实现了将3D坐标向下映射到2D的第一个重要步骤。如果你已经设法让这一切都有效,我建议尝试多个点并将它们连接成形状。同时尝试移动相机位置以查看视角如何变化,因为您很快就会看到它看起来有多逼真。

此外,如果这对您有效,您可以继续让相机不仅能够改变其在3D世界中的位置,还能够改变其在pitch角度中的视角。我现在不会完全讨论这个问题,但基本思想是使用3D世界转换矩阵。你可以阅读它们here,但它们确实变得非常复杂,但如果你走得这么远,我可以给你计算。

答案 1 :(得分:1)

阅读(旧式)OpenGL规范可能会有所帮助:

https://www.khronos.org/registry/OpenGL/specs/gl/glspec14.pdf

见第2.10节

另外:

https://www.khronos.org/opengl/wiki/Vertex_Transformation

可能会提供更具体的例子。

另外,对于"正确的数学"查找4x4矩阵,投影和齐次坐标。

https://en.wikipedia.org/wiki/Homogeneous_coordinates