在OpenGL中围绕坐标旋转四边形

Posted

技术标签:

【中文标题】在OpenGL中围绕坐标旋转四边形【英文标题】:Rotating a quad around a coordinate in OpenGL 【发布时间】:2020-01-05 13:40:16 【问题描述】:

我目前正在使用 Python 和 OpenGL 编写一个主要的飞行显示器。 由于我对 OpenGL 的经验为零(一般编码经验也很少)我确实在最简单的功能实现方面遇到了困难,但直到现在我已经走到了这一步:

我现在的问题是根据滚动数据围绕视口的中心点旋转人造地平线(400x240)。 我的视口是 800x480,四边形代表人工地平线,大小为 1000x2880。

显示俯仰数据很容易,因为 1 度等于视口/水平纹理上的 8 个像素。

Numbers.p_offset = -Data.pitch*8,我可以将其添加到四边形的所有四个 y 坐标中。

def horizon():

    glBindTexture(GL_TEXTURE_2D, horizontexture)

    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_TEXTURE_2D)
    glColor4f(1, 1, 1, 1)

    glBegin(GL_QUADS)
    glTexCoord2f(0, 1); glVertex2f(-100, -1200+Numbers.p_offset)
    glTexCoord2f(1, 1); glVertex2f(900, -1200+Numbers.p_offset)
    glTexCoord2f(1, 0); glVertex2f(900, 1680+Numbers.p_offset)
    glTexCoord2f(0, 0); glVertex2f(-100, 1680+Numbers.p_offset)
    glEnd()

    glDisable(GL_TEXTURE_2D)

显示滚动数据并不容易(-180° 到 180°),因为滚动的变化会改变 x- y-四边形的坐标。首先,需要应用俯仰偏移(将四边形的垂直中心线保持在视口中心),然后应用与滚动相对应的旋转。我无法弄清楚如何计算偏移滚动会导致的数学问题,所以我正在寻找一个解决方案,如何使用一些我还不知道的 OpenGL 功能来完成它。

我找到的所有教程和问题/答案都专门询问如何围绕自己的中心点而不是另一个坐标旋转四边形。


问题:如何在 OpenGL 和 Python 的正交投影中围绕特定坐标旋转四边形?

【问题讨论】:

【参考方案1】:

首先你必须定义枢轴:

pivot_x = (900 + (-100)) / 2
pivot_y = (-1200 + 1680) / 2

如果你想围绕一个轴旋转一个对象,那么你必须:

以这种方式翻译对象,即枢轴位于原点 (0, 0, 0):glTranslatef(-pivot_x, -pivot_y, 0)

在视图的xy平面旋转对象:glRotate(angle, 0, 0, 1)

以枢轴回到其原始位置的方式平移矩形:glTranslatef(pivot_x, pivot_y, 0)

由于glTranslatedglRotated 等操作定义了一个新矩阵并将其与当前矩阵相乘,因此必须以相反的顺序执行此指令。 使用glPushMatrix / glPopMatrix 保存和恢复操作前后的当前矩阵。例如:

def horizon():

    pivot_x = (900 + (-100)) / 2
    pivot_y = (-1200 + 1680) / 2
    glPushMatrix()

    # rotate around pivot (roll)
    glTranslatef(pivot_x, pivot_y, 0)
    glRotatef(angle, 0, 0, 1)
    glTranslatef(-pivot_x, -pivot_y, 0)

    # apply pitch
    glTranslatef(0, Numbers.p_offset, 0)

    glBindTexture(GL_TEXTURE_2D, horizontexture)

    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_TEXTURE_2D)
    glColor4f(1, 1, 1, 1)

    glBegin(GL_QUADS)
    glTexCoord2f(0, 1); glVertex2f(-100, -1200)
    glTexCoord2f(1, 1); glVertex2f(900, -1200)
    glTexCoord2f(1, 0); glVertex2f(900, 1680)
    glTexCoord2f(0, 0); glVertex2f(-100, 1680)
    glEnd()

    glDisable(GL_TEXTURE_2D)

    glPopMatrix()

(另见How to use Pivot Point in Transformations 和How to rotate a 2D line in PyOpenGL?)

【讨论】:

这解决了 90%。现在的问题是滚动是在俯仰之前应用的,这意味着垂直中心线不在中心。 This 是滚动 = 90° 和俯仰 = 30 时的样子。 glVertex2f() 中的Numbers.p_offsethorizon 中应用间距。应用音高后是否可以平移和旋转四边形?我试图在创建四边形和纹理映射后粘贴新代码,但这只是忽略了代码。如果在horizon 之前应用滚动(旋转),则会出现同样的问题,因为如果在 y 平面(俯仰)平移之前应用旋转,四边形垂直中心线不再居中。 @GittingGud 所以可能枢轴是错误的。试试pivot_y = (-1200 + 1680) / 2 解决了这个问题,事后看来,这也是合乎逻辑的。 y 平移(p_offset)不影响四边形的大小,因此不影响枢轴点。感谢您的帮助! @GittingGud 注意,pich 可以通过glTranslatef(0, Numbers.p_offset, 0) 申请。我已经在答案中改变了这一点。

以上是关于在OpenGL中围绕坐标旋转四边形的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - 围绕 Y 轴旋转“曲线”

在 C++/OpenGL 中投影一个围绕另一个对象旋转的对象

opengl旋转曲面画立体图

如何在 OpenGL 中围绕 Z 轴中心旋转对象?

在 OpenGL 中绘制一个绕 Y 轴旋转的 Cog

在OpenGL中围绕特定点旋转对象