我有一些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.
    

    最佳答案

    在OpenGL中,您指定的矩阵会与现有矩阵的右边相乘,而顶点位于表达式的最右边。

    因此,您指定的最后一个操作在几何本身的坐标系中。
    (第一个通常是 View 变换,即相机到世界的变换的逆。)

    Bahbar提出了一个很好的观点,您需要考虑缩放的中心点。 (或旋转的枢轴点。)通常在此处平移,旋转/缩放,然后向后平移。 (或一般来说,先应用基础变换,然后进行逆运算)。这称为Change of Basis,您可能想继续阅读。

    无论如何,要获得有关其工作原理的直观信息,请尝试使用一些简单的值(零等),然后对其稍加更改(也许是动画),然后查看输出会发生什么。然后,更容易查看变换对几何体的实际作用。

    更新

    订单被“撤消”直觉在初学者OpenGL编码器中相当普遍。我一直在辅导计算机图形学类(class),并且许多人以类似的方式使用react。如果在渲染变换和几何结构的树(场景图)时考虑使用pushmatrix / popmatrix,则更容易考虑OpenGL如何做到这一点。然后,当前的事物顺序变得很自然,而相反的事物将使得很难完成任何有用的事情。

    关于opengl - OpenGL:缩放然后翻译?如何?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2258910/

    10-13 22:43