透视投影中的 3D 场景平移 (OpenGL)

2021-12-19 00:00:00 opengl c++ renderer

我设计了一个 C++ 类,将用户从轨迹球旋转、缩放和平移中抽象出来.我已经按预期进行了旋转(使用轨迹球)和缩放.但是,平移不会按预期进行.当我选择一个点并拖动时,我希望在完成拖动时,选择的点继续位于鼠标下方.我对透视投影中平移的理解如下.目标和相机位置都会受到平移操作的影响.相机目标和相机位置(眼睛)应与拖动成比例地平移.比例(可能不是常数)应基于 z 深度.

I have designed a C++ class that abstracts the user from trackball rotation, zooming and panning. I have got the rotation (using trackball) and zooming working as expected. However, panning does not behave as expected. When I pick a point and drag, I expect that on finishing drag, the picked point continues to be under the mouse. My understanding of panning in perspective projection is as follows. The target and the camera position, both will be affected by a pan operation. The camera target and the camera position (eye) should be translated proportional to the drag. The proportionality (may not be constant) should be based on z depth.

平移在正交投影中是直接的,但在透视上会造成问题.如果能够解释OpenGL 的数学和实现细节,将会很有用.

Panning is straight forward in orthographic projection but poses a problem in perspective. It will be useful if one can explain the math and the implementation detail for OpenGL.

推荐答案

我不知道 OpenGL 的具体细节,但如果我正确理解你的问题,我可以帮助解决数学问题:

I don't know about the OpenGL specifics, but if I understand your question correctly I can help out with the mathematics:

我假设您已经选择了该对象,方法是单击该对象并因此发送"一条光线穿过您的场景并击中定位点中的对象 p.

I assume you have already selected the object, by clicking the object and thus "sending" a ray through your scene that hits your object in the anchorpoint p.

了解以下内容:

现在您沿着矢量 t 拖动鼠标.使用截距定理,您可以轻松计算向量 s,通过该向量必须将 p 转换为将其保持在光标下":

Now you drag your mouse along vector t. Using the intercept theorem you can easily calculate the vector s by which p has to be translated to "keep it under the cursor":

|p|/|q|= |s|/|t|

|p| / |q| = |s| / |t|

|s|= ( |p|/|q| ) * |t|

|s| = ( |p| / |q| ) * |t|

s 与 t 平行,所以它是 t 归一化乘以 |s|:

s is parallel to t, so it is t normalized multiplicated by |s|:

s = t/|t|* |s|

s = t / |t| * |s|

s = t/|t|* ( |p|/|q| ) * |t|

s = t / |t| * ( |p| / |q| ) * |t|

s = t * ( |p|/|q| )

s = t * ( |p| / |q| )

如果你在平移,你在做完全相同的事情,只是你没有通过 s 移动 p,但是你必须通过 -s.

If you are panning, you are doing the exact same thing, just that you are not shifting p by s, but you have to translate your whole scene by -s.

相关文章