我有一些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.
当目标原点为0时,对于给定维度,这可以完全按预期工作。但是,如果例如x的原点是非零的,则结果仍然按比例缩放,但看起来像是在该轴上被转换到接近零的某个位置 - 实际上它与dest.x为零时有所不同。
有人能指出我忽略的显而易见的问题吗?
谢谢!
最终更新 根据Bahbar和Marcus下面的答案,我进行了更多实验并解决了这个问题。Adam Bowen的评论是提示。我遗漏了两个关键事实:
- 我需要围绕我关心的几何形状的中心进行缩放。
- 我需要按直觉的相反顺序应用变换(对我而言)。
第一个回顾起来有些显然。但对于其他像我一样的优秀程序员/糟糕的数学家来说:事实证明我的直觉是基于Red Book中称为“大型,固定坐标系统”的概念,其中存在一个绝对平面,你的几何形状在该平面上使用变换移动。这是可以的,但考虑到将多个变换堆叠成一个矩阵背后的数学性质,它与实际情况相反(请参见下面的答案或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.