Opengl 如何确定摄影机方向和平面之间的交点?

Opengl 如何确定摄影机方向和平面之间的交点?,opengl,math,3d,Opengl,Math,3d,我有一个三维场景,它有一个无限水平面(平行于xz坐标),高度为H,沿Y垂直轴 我想知道如何确定我的相机轴和这个平面之间的交点 相机由视图矩阵和投影矩阵定义。对于一般线平面交点,有很多答案和教程 你的情况很简单,因为平面是水平的 我假设相机在C(cx,cy,cz)上,它看T(tx,ty,tz)。 然后,可以通过以下方式定义直线摄影机目标: cx - x cy - y cz - z ------ = ------ = ------ /// These are t

我有一个三维场景,它有一个无限水平面(平行于xz坐标),高度为H,沿Y垂直轴

我想知道如何确定我的相机轴和这个平面之间的交点


相机由视图矩阵和投影矩阵定义。

对于一般线平面交点,有很多答案和教程

你的情况很简单,因为平面是水平的

我假设相机在
C(cx,cy,cz)
上,它看
T(tx,ty,tz)

然后,可以通过以下方式定义直线摄影机目标:

cx - x     cy - y     cz - z
------  =  ------  =  ------        /// These are two independant equations
tx - cx    ty - cy    tz - cz
对于水平面,只需要一个方程:
y=H
。 在直线方程中替换该值,得到

(cx-x)/(tx-cx) = (cy-H)/(ty-cy)
(cz-z)/(tz-cz) = (cy-H)/(ty-cy)
所以


当然,如果您的相机看起来也是水平线,则没有解决方案。

这里有两个子问题:1)从相机矩阵提取位置和视图方向。2) 计算视图光线与平面之间的交点

提取位置和视图方向

视图矩阵描述了如何将点从世界空间转换到视图空间。OpenGL中的视图空间通常是这样定义的,即相机位于原点并朝-z方向观看

要获得相机的位置,我们必须将视图空间的原点[0,0,0]变换回世界空间。从数学上讲,我们必须计算:

camera_pos_ws = inverse(view_matrix) * [0,0,0,1]
但是当我们看这个方程时,我们会发现我们只在逆矩阵的第四列中,它包含1

摄像机的方向可以通过类似的计算得到。我们知道摄影机在视图空间中沿-z方向观看,因此世界空间方向由

camera_dir_ws = inverse(view_matrix) * [0,0,-1,0];
inv(M) = [ transpose(R)  -T ]
                0         1
同样,当我们看方程时,我们会看到这只考虑了逆矩阵的第三行,由2给出

计算交叉点

现在我们知道了摄像机的位置p和观察方向D,因此我们必须沿着光线找到x,z值
R(x,y,z)=p+l*D
,其中y等于H。因为只有一个未知值,l,我们可以从

y = Py + l * Dy
H = Py + l * Dy
l = (H - Py) / Dy
然后,通过将l粘贴回光线方程中给出交点

注释

1索引假设矩阵存储在列主线性阵列中

2注意,矩阵的逆形式

M = [  R T ]
       0 1
,其中R是正交3x3矩阵,由下式给出

camera_dir_ws = inverse(view_matrix) * [0,0,-1,0];
inv(M) = [ transpose(R)  -T ]
                0         1

您如何定义相机及其方向?可能与@Ripi2重复我有4x4 viewMatrix和projectionMatrix。谢谢您的帮助。在你的方程式中有点我不明白。向量XC与向量T是共线的,所以我认为它应该是(cx-x)/tx=(cy-y)/ty=(cz-z)/tz,对吗?不,不对<代码>cx、tx、cy、ty等是坐标,而不是矢量分量。你的方程式错了。谢谢你的详细回答。您确定摄像头位置ws=[-view\u matrix[13]、-view\u matrix[14]、-view\u matrix[15]?是不是:camera_pos_ws=[-view_matrix[12],-view_matrix[13],-view_matrix[14]?你完全正确。谢谢你的反馈,我改正了错误。如果您有任何其他意见或发现更多错误,请告诉我:)“where y=0”您是指“where y=H”吗?(H=沿Y轴的平面高程)Ups,完全覆盖“高度H”部分。现在还改正了。考虑另一种写矩阵变换的方法:代码> y= Mx= r*x+t</代码>;将此项反转,即可获得
x=inv(M)*y=transpose(R)*(y-T)
。因此,
inv(M)
的最后一列不是
-T
,而是
-transpose(R)*T
inv(M) = [ transpose(R)  -T ]
                0         1