我设计了一个 C++ 类,将用户从轨迹球旋转、缩放和平移中抽象出来。我已经按预期进行了旋转(使用轨迹球)和缩放。但是,平移的行为与预期不同。当我选择一个点并拖动时,我希望在完成拖动时,选择的点继续在鼠标下方。我对透视投影中平移的理解如下。目标和摄像机位置都会受到平移操作的影响。摄像机目标和摄像机位置(眼睛)应与拖动成比例平移。比例(可能不是恒定的)应基于 z 深度。
平移在正交投影中是直截了当的,但在透视方面存在问题。如果有人能解释OpenGL 的数学和实现细节,那将会很有用。
我不知道 OpenGL 的细节,但如果我正确理解了你的问题,我可以帮助解决数学问题:
我假设您已经选择了该对象,方法是单击该对象,从而通过您的场景“发送”一条射线,该射线在锚点p中击中您的对象。
要了解以下内容:
现在你沿着向量t拖动鼠标。使用截距定理,您可以轻松计算向量s,通过该向量p必须转换为“将其保持在光标下”:
|p| / |q| = |s| / |t|
|s| = ( |p| / |q| ) * |t|
s 与 t 平行,所以它是 t 归一化乘以 |s|:
s = t / |t| * |s|
s = t / |t| * ( |p| / |q| ) * |t|
s = t * ( |p| / |q| )
如果您正在平移,您正在做完全相同的事情,只是您没有将p移动s,但您必须将整个场景平移-s。
在你的鼠标下不可能有终点。透视模式下的平移可以通过两种方式完成。一个是平移相机,另一个是旋转相机。平移相机将导致对象旋转以供用户查看。用于平移的旋转相机有两个约束。一种是不改变相机位置,另一种是停止相对于相机方向的旋转。即,旋转轴应平行于相机右和上矢量形成的平面。