给定相机和视平面,求2D点的3D坐标

7

我希望从相机通过视平面生成光线。为了做到这一点,我需要我的相机位置(“眼睛”),上、右和朝向向量(其中朝向是从相机指向相机所看物体的方向的向量)以及P,视平面上的点。一旦我拥有了这些,生成的射线就是:

ray = camera_eye + t*(P-camera_eye);

其中t是沿着光线的距离(暂时假设t = 1)。

我的问题是,如何得到点P的3D坐标,假设它位于观察平面上(i,j)的位置?假设已知观察平面的左上角和右下角。

注意:观察平面实际上不是一个平面,因为它不会在所有方向上无限延伸。相反,可以将此平面视为widthxheight的图像。在x方向上,范围是0-宽度,并且在y方向上,范围是0-高度。我希望找到第(i,j)个元素的三维坐标,其中0<i<width且0<j<height。


它可以处于任何角度。但是你知道观察平面垂直于相机,并且朝向camera_towards的方向。因此,camera_towards是垂直于观察平面的向量,而camera_eye+camera_towards是尺寸为width*height的观察平面的中心。 - Myx
抱歉 - 我删除了我的评论,因为我最终更好地理解了问题。但是(@all)为了清晰起见,因为Myx发布了回复,我问是否观看平面可以以任何角度,还是始终相对于相机以某个角度。 - Cam
3个回答

2

一条直线和一个平面相交的一般解决方案,请参见http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/

你所使用的特定图形库(如OpenGL/DirectX等)可能有标准方法来解决此问题。

编辑:您正在尝试查找屏幕点(例如鼠标指针)与场景中的3D对象的3D交点吗?


我不是在尝试查找一条直线和平面的交点,而是在尝试生成该直线。也就是说,该直线的第二个端点未知,我正在尝试解决这个问题。 " viewing plane "只是术语,它实际上不是一个平面(因为平面在所有方向上都无限延伸)。相反,这个“平面”具有固定的尺寸,我正在尝试找出平面上每个点的三维坐标(平面上的点在x方向上从0到宽度,在y方向上从0到高度范围内)。 - Myx
这就是这些算法所实现的。您可以识别出用像素表示的多边形,以及其中的重心坐标。 - greyfade

0

为了计算P,你需要知道相机到近裁剪面(屏幕)的距离、近裁剪面上窗口的大小(或视角,你可以根据视角计算出窗口大小)以及渲染窗口的大小。

  1. 将屏幕位置缩放到范围-1<x<+1和-1<y<+1的区间内,其中+1表示顶部/右侧,-1表示底部/左侧
  2. 通过视窗尺寸缩放标准化的x、y值
  3. 通过相机的右向量和上向量进行缩放并求和
  4. 加上查看向量,按裁剪平面距离进行缩放

实际上,你得到:

p = at * near_clip_dist + x * right + y * up

x和y分别代表:

x = (screen_x - screen_centre_x) / (width / 2) * view_width
y = (screen_y - screen_centre_y) / (height / 2) * view_height

视图宽度(view_width)和宽度(width)有什么区别? - Myx
@Myx:width是屏幕的宽度,通常以像素为单位。view_width是窗口在近裁剪平面上的宽度,以世界坐标表示,通过该窗口摄像机进行观察。 - Skizz

0

当我直接将建议的公式插入到我的程序中时,我没有得到正确的结果(可能需要进行一些调试)。我的初始问题似乎在于对插值角点的(x,y,z)坐标的误解。我曾经单独处理x、y、z坐标,但实际上不应该这样做(这可能是特定于应用程序的,因为相机可以朝任何方向定位)。相反,解决方案是简单地插值视图平面的角点:

  • 在i方向插值底部角点以获得P1
  • 在i方向插值顶部角点以获得P2
  • 在j方向插值P1和P2以获得最终点的世界坐标

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接