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

发布于 2024-07-14 12:41:28 字数 497 浏览 9 评论 0原文

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

谁能向我解释一下平移、缩放和旋转通常是如何实现的?

例如,通过平移和缩放,这只是我调整我的视口吗? 因此,我绘制并绘制组成地图的所有线条,然后当用户单击并拖动时调整我的视口?

对于平移,它是否会改变我的视口的 x/y 值,而对于缩放,它是否会增加/减少我的视口一定量? 对于轮换呢?

对于旋转,我是否必须对代表校园地图的每条折线进行仿射变换? 在大小合适的地图上即时执行此操作会不会很昂贵?

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


例如,如果您访问此链接,您'你会看到他通过修改视口来描述平移和缩放,就像我上面所描述的那样。

这不正确吗?

Using OpenGL I'm attempting to draw a primitive map of my campus.

Can anyone explain to me how panning, zooming and rotating is usually implemented?

For example, with panning and zooming, is that simply me adjusting my viewport? So I plot and draw all my lines that compose my map, and then as the user clicks and drags it adjusts my viewport?

For panning, does it shift the x/y values of my viewport and for zooming does it increase/decrease my viewport by some amount? What about for rotation?

For rotation, do I have to do affine transforms for each polyline that represents my campus map? Won't this be expensive to do on the fly on a decent sized map?

Or, is the viewport left the same and panning/zooming/rotation is done in some otherway?


For example, if you go to this link you'll see him describe panning and zooming exactly how I have above, by modifying the viewport.

Is this not correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

强者自强 2024-07-21 12:41:28

它们是通过在绘制场景之前应用一系列 glTranslate、glRotate 命令(表示相机位置和方向)来实现的。 (从技术上讲,你正在旋转整个场景!)

有像 gluLookAt 这样的实用函数,它抽象了一些关于此的细节。

为了简单起见,假设您有两个代表相机的向量:位置和方向。

gluLookAt 获取位置、目的地和向上向量。

如果你实现一个向量类,destinaion=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 )

说实话,这有点黑客的方法。

正确的做法是使用更“复杂”的数据结构来表示相机的“方向”,而不仅仅是前进方向。 然而,由于您才刚刚开始,所以最好一次一步地采取行动。

They're achieved by applying a series of glTranslate, glRotate commands (that represent camera position and orientation) before drawing the scene. (technically, you're rotating the whole scene!)

There are utility functions like gluLookAt which sorta abstract some details about this.

To simplyify things, assume you have two vectors representing your camera: position and direction.

gluLookAt takes the position, destination, and up vector.

If you implement a vector class, destinaion = position + direction should give you a destination point.

Again to make things simple, you can assume the up vector to always be (0,1,0)

Then, before rendering anything in your scene, load the identity matrix and call gluLookAt

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );

Then start drawing your objects

You can let the user span by changing the position slightly to the right or to the left. Rotation is a bit more complicated as you have to rotate the direction vector. Assuming that what you're rotating is the camera, not some object in the scene.

One problem is, if you only have a direction vector "forward" how do you move it? where is the right and left?

My approach in this case is to just take the cross product of "direction" and (0,1,0).

Now you can move the camera to the left and to the right using something like:

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

You can move forward using the "direction vector", but IMO it's better to restrict movement to a horizontal plane, so get the forward vector the same way we got the right vector:

forward = cross( up, right )

To be honest, this is somewhat of a hackish approach.

The proper approach is to use a more "sophisticated" data structure to represent the "orientation" of the camera, not just the forward direction. However, since you're just starting out, it's good to take things one step at a time.

浮萍、无处依 2024-07-21 12:41:28

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

All of these "actions" can be achieved using model-view matrix transformation functions. You should read about glTranslatef (panning), glScalef (zoom), glRotatef (rotation). You also should need to read some basic tutorial about OpenGL, you might find this link useful.

白云不回头 2024-07-21 12:41:28

通常,每当您在 opengl 中引用 3d 空间中的任何点时,都会应用三个步骤。

给定一个本地点

  • Local -> 世界改造
  • 世界-> 相机变换
  • 相机-> 屏幕变换(通常是投影。取决于您使用的是透视还是正交)

这些变换中的每一个都采用您的 3d 点,并乘以矩阵。

当你旋转相机时,它通常会改变世界 -> 通过将变换矩阵乘以旋转/平移/缩放仿射变换来进行相机变换。 由于每帧都会重新渲染所有点,因此新矩阵将应用于您的点,并给出旋转的外观。

Generally there are three steps that are applied whenever you reference any point in 3d space within opengl.

Given a Local point

  • Local -> World Transform
  • World -> Camera Transform
  • Camera -> Screen Transform (usually a projection. depends on if you're using perspective or orthogonal)

Each of these transforms is taking your 3d point, and multiplying by a matrix.

When you are rotating the camera, it is generally changing the world -> camera transform by multiplying the transform matrix by your rotation/pan/zoom affine transformation. Since all of your points are re-rendered each frame, the new matrix gets applied to your points, and it gives the appearance of a rotation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文