缩放、平移和旋转是如何工作的?

6

使用OpenGL,我正在尝试绘制校园的原始地图。

有人能解释一下通常如何实现平移、缩放和旋转吗?

例如,对于平移和缩放,这只是我调整视口吗?所以我绘制出组成我的地图的所有线条,然后当用户单击并拖动时,它会调整我的视口?对于平移,它是否移动我的视口的x/y值,对于缩放,它是否增加/减少我的视口一定量?旋转呢?

对于旋转,我是否需要为表示我的校园地图的每个折线执行仿射变换?在一个相当大的地图上即时执行这些操作不会很费时间吗?

或者,视口保持不变,平移/缩放/旋转是以其他方式完成的吗?


例如,如果您访问此链接,您将看到他描述如何通过修改视口来精确地进行平移和缩放,就像我上面所描述的那样。
这不正确吗?
3个回答

7
它们是通过在绘制场景之前应用一系列的glTranslate、glRotate命令(代表相机位置和方向)来实现的。(技术上,你正在旋转整个场景!)
有一些实用函数,比如gluLookAt,可以抽象出一些关于此的细节。
为了简化事情,假设您有两个表示相机的向量:位置和方向。
gluLookAt需要位置、目标和上向量。
如果您实现了一个向量类,那么destination = position + direction应该给您一个目标点。
再次简化,您可以假设上向量始终为(0,1,0)。
然后,在渲染场景中的任何内容之前,加载身份矩阵并调用gluLookAt。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );

然后开始绘制你的对象。

您可以通过将位置略微向右或向左移动来让用户跨越。旋转则稍微复杂一些,因为您必须旋转方向向量。假设您要旋转的是相机,而不是场景中的某个对象。

一个问题是,如果您只有一个方向向量“前进”,那么如何移动它?右侧和左侧在哪里?

在这种情况下,我的方法是仅采用“方向”和(0,1,0)的叉积。

现在,您可以使用类似以下内容的东西将相机向左和向右移动:

position = position + right * amount; //amount < 0 moves to the left

您可以使用“方向向量”向前移动,但我认为最好将移动限制在水平面上,因此获取前向量的方式与获取右向量的方式相同:

forward = cross( up, right )

说实话,这有点像是一个hackish的方法。

正确的方法是使用更“复杂”的数据结构来表示相机的“方向”,而不仅仅是前进方向。但是,既然你刚刚开始,一步步来还是很好的。


2
请允许我补充一点,glViewport设置的“视口”在此过程中并没有起到任何作用。视口确定了您将要渲染的窗口区域(实际上并非如此,但现在可以这样考虑),通常会跨越整个窗口。 - Thomas

4

所有这些“操作”都可以使用模型-视图矩阵变换函数来实现。您应该了解glTranslatef(平移)、glScalef(缩放)和glRotatef(旋转)。您还需要阅读一些关于OpenGL的基础教程,您可能会发现这个链接有用。


1
通常在OpenGL中引用3D空间中的任何点时,都会应用三个步骤。
给定一个本地点
- 本地 -> 世界变换 - 世界 -> 相机变换 - 相机 -> 屏幕变换(通常是投影。这取决于您使用透视还是正交)
每个转换都将您的3D点乘以矩阵。
当您旋转相机时,通常会通过将变换矩阵与旋转/平移/缩放仿射变换相乘来更改世界->相机变换。由于所有点都在每帧重新渲染,因此新矩阵被应用于您的点,并呈现旋转外观。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接