Math 3D:在屏幕上保持水平线在同一高度,而不考虑摄像头';s变焦

Math 3D:在屏幕上保持水平线在同一高度,而不考虑摄像头';s变焦,math,3d,camera,projection-matrix,Math,3d,Camera,Projection Matrix,我有一个奇怪的用例 这些变量是已知的: 摄像机变焦(或视野) 摄像机绕Y轴和Z轴旋转(方向)=0 现在,我希望在屏幕上以特定的二维高度“YY”绘制地平线(地平线位置=(0,0,无限))。摄像机的X轴旋转必须是什么,以使地平线在“YY”处绘制 你可能会问我为什么需要这个:嗯,当我改变相机变焦时,地平线在屏幕上的位置会改变(在所有情况下,X轴旋转=0除外)。我需要能够改变相机变焦,并保持地平线不变(相对于其2D位置)。好的,这只能通过相应地改变X轴旋转来实现。对于定义良好的对称视锥,可以通过一些

我有一个奇怪的用例

这些变量是已知的:

  • 摄像机变焦(或视野)

  • 摄像机绕Y轴和Z轴旋转(方向)
    =0

现在,我希望在屏幕上以特定的二维高度“YY”绘制地平线(地平线位置
=(0,0,无限)
)。摄像机的X轴旋转必须是什么,以使地平线在“YY”处绘制


你可能会问我为什么需要这个:嗯,当我改变相机变焦时,地平线在屏幕上的位置会改变(在所有情况下,X轴旋转
=0
除外)。我需要能够改变相机变焦,并保持地平线不变(相对于其2D位置)。好的,这只能通过相应地改变X轴旋转来实现。

对于定义良好的对称视锥,可以通过一些简单的几何图形找到解决方案:

我假设
YY
在标准化设备坐标中(范围从-1到1)。如果它们是像素坐标,则必须转换它们

我已选择投影平面距离相机1个单位。但任何其他距离都可以。然后,距离
y'
就是

y' = YY * H/2
H/2
是半屏幕高度,可通过以下公式计算:

H/2 = tan (fovy/2)
其中
fovy
是相机在垂直方向上的视野

您希望为旋转找到角度
alpha
。这很简单:

tan alpha = y' / 1 = YY * tan(fovy / 2)
    alpha = atan(YY * tan(fovy / 2)
注意方向。正值指定向下旋转


对于任意投影,该问题可以解析地解决:

假设我们有投影矩阵
p
和视图矩阵
V
,我们要求解:

w-clip(P * V * (0 0 1 0)^T) = (... YY ...)
由于您只希望允许相机围绕x轴进行平移和旋转,
V
的形式如下:

    / 1  0           0          tx \
V = | 0  cos alpha  -sin alpha  ty |
    | 0  sin alpha   cos alpha  tz |
    \ 0  0           0          1  /
这就产生了一个方程式:

YY = (p23 * cos alpha - p22 * sin alpha) / (p43 * cos alpha - p42 * sin alpha)
其中,
pij
i
-th行和
j
-th列中
p
的条目


使用您最喜欢的符号解算器获得alpha的解,您可以重新计算视图矩阵。

地面是平面、球体、椭球体还是网格?这与此无关。地平线是一条无限远的无限水平线,只有当你的Zfar足够大并且你不想看到地面上的东西时,这才是真的。。。如果您添加围绕z的旋转,那么它根本不是水平的。。。