我有一个3D场景,在Y垂直轴的高度H处有一个无限水平面(平行于xz坐标)。
我想知道如何确定相机轴与此平面之间的交点。
相机由视图矩阵和投影矩阵定义。
答案 0 :(得分:1)
对于一般的线平面交叉点,有很多答案和教程。
由于飞机是水平的,你的情况很简单。
我认为相机位于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)
所以
x = cx - (tx-cx)*(cy-H)/(ty-cy)
y = H
z = cz - (tz-cz)*(cy-H)/(ty-cy)
当然,如果你的相机看起来是水平线,那么ty=cy
并没有解决方案。
答案 1 :(得分:1)
这里有两个子问题:1)从摄像机矩阵中提取位置和视图方向。 2)计算视线与平面之间的交点。
提取位置和视图方向
视图矩阵描述了点如何从世界空间转换为视图空间。通常定义OpenGL中的视图空间,使得摄像机位于原点并朝向-z方向。
要获得相机的位置,我们必须将视图空间的原点[0,0,0]转换回世界空间。从数学上讲,我们必须计算:
camera_pos_ws = inverse(view_matrix) * [0,0,0,1]
但是在查看方程时,我们会看到我们只对逆矩阵的第4列感兴趣,其中包含 1
camera_pos_ws = [-view_matrix[12], -view_matrix[13], -view_matrix[14]]
可以通过类似的计算找到相机的方向。我们知道相机在视野中看-z方向,因此世界空间方向由
给出camera_dir_ws = inverse(view_matrix) * [0,0,-1,0];
再次,在查看等式时,我们将看到这只考虑逆矩阵的第三行,由 2
给出camera_dir_ws = [-view_matrix[2], -view_matrix[6], -view_matrix[10]]
计算交叉点
我们现在知道摄像机位置P和视图方向D,因此我们必须找到沿着光线R(x,y,z) = P + l * D
的x,z值,其中y等于H.因为只有一个未知的,l,我们可以从
y = Py + l * Dy
H = Py + l * Dy
l = (H - Py) / Dy
然后通过将l粘贴回射线方程来给出交点。
备注强>
1 指数假设矩阵存储在列主线性数组中。
2 注意,表格
的矩阵的逆矩阵M = [ R T ]
0 1
,其中R是正交3×3矩阵,由
给出inv(M) = [ transpose(R) -T ]
0 1