【发布时间】:2011-01-16 13:34:09
【问题描述】:
我有一些 2D 几何图形。我想在我的几何图形周围做一些边界矩形,然后在平面上的其他地方渲染一个较小的版本。这里或多或少是我必须进行缩放和翻译的代码:
// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
float translateX = dest.x - source.x;
float translateY = dest.y - source.y;
glScalef(scaleX, scaleY, 0.0);
glTranslatef(translateX, translateY, 0.0);
// Draw geometry in question with its normal verts.
当 dest 原点为 0 时,对于给定维度,这完全符合预期。但是,如果 x 的原点不为零,则结果仍然可以正确缩放,但看起来像 (?) 它被转换为接近零的值无论如何,在那个轴上 - 事实证明它与 dest.x 为零时不完全相同。
有人能指出我明显遗漏的东西吗?
谢谢!
最终更新 根据 Bahbar 和 Marcus 在下面的回答,我做了更多的实验并解决了这个问题。亚当鲍文的评论是提示。我遗漏了两个关键事实:
- 我需要围绕我关心的几何图形的中心进行缩放。
- 我需要以与直觉相反的顺序应用变换(对我而言)。
回想起来,第一个是显而易见的。但是对于后者,对于像我这样的其他优秀程序员/糟糕的数学家:结果我的直觉是在Red Book 所谓的“大固定坐标系”中运行,其中有一个绝对平面,并且您的几何图形四处移动在那个平面上使用变换。这没关系,但考虑到将多个变换叠加到一个矩阵背后的数学性质,这与实际工作方式相反(请参阅下面的答案或红皮书了解更多信息)。基本上,这些转换以“相反的顺序”“应用”到它们在代码中的出现方式。这是最终的工作解决方案:
// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
Point sourceCenter = centerPointOfRect(source);
Point destCenter = centerPointOfRect(dest);
glTranslatef(destCenter.x, destCenter.y, 0.0);
glScalef(scaleX, scaleY, 0.0);
glTranslatef(sourceCenter.x * -1.0, sourceCenter.y * -1.0, 0.0);
// Draw geometry in question with its normal verts.
【问题讨论】: