我有一些二维几何。我想在我的几何体周围获取一些边界矩形,然后在平面上的其他地方渲染它的较小版本。以下或多或少是我必须进行缩放和翻译的代码:
// 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.
当目标原点为 0 时,对于给定维度,这完全按照预期工作。但是,如果 x 的原点非零,则结果仍然正确缩放,但看起来(?)它在该轴上转换为接近零的值无论如何——事实证明它与 dest.x 为零时并不完全相同。
有人可以指出我遗漏的一些明显的东西吗?
Thanks!
最终更新根据下面巴巴尔和马库斯的回答,我做了一些更多的实验并解决了这个问题。亚当·鲍文 (Adam Bowen) 的评论是一个线索。我遗漏了两个关键事实:
- 我需要围绕我关心的几何中心进行缩放。
- 我需要以与直觉相反的顺序应用变换(对我来说)。
回想起来,第一个是显而易见的。但对于后者,对于像我这样的其他优秀程序员/糟糕数学家来说:事实证明我的直觉是在运作的Red Book https://rads.stackoverflow.com/amzn/click/com/0321552628称为“大固定坐标系”,其中有一个绝对平面,并且您的几何体使用变换在该平面上移动。这没关系,但考虑到将多个变换堆叠到一个矩阵背后的数学性质,这与实际工作方式相反(请参阅下面的答案或红皮书了解更多信息)。基本上,变换是按照它们在代码中出现的“相反顺序”“应用”的。这是最终的工作解决方案:
// 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.