opengl - 在 OpenGL 中通过超球面导航

标签 opengl

也许这适合 math.stackexchange.com,但由于我是在 OpenGL 中编程的,所以我会在这里问。

我有一个宇宙飞船游戏的想法,其中世界被限制在 4-D 超球体(也称为 3 球体)的表面。因此,从内部看它就像一个 3 维世界,但通过向各个方向导航,我永远不会离开 3 维球体的有限体积。

为了将 3-shpere 表示为“平坦”的 3-D 空间,我使用了立体投影,作为 GLSL 着色器实现起来非常简单,只需将输入向量除以其 w 坐标即可。

为了表示对象的顶点,我使用标准化的 4d 向量,使得 x²+y²+z²+w²=1,从而将它们保持在 3 维球内。

首先要解决的问题是旋转。但我很快发现普通的 3d 旋转矩阵足以在 3d 投影中围绕观察者旋转世界,因为它不会弄乱 w 坐标(很像围绕 z 轴旋转球体也会旋转它的立体投影)。

然后我发现沿 w 轴旋转等同于 3d 投影内的平移(只是不可交换,作为“平坦”空间上的普通 3d 平移),然后我可以通过使用简单的 around 沿轴平移轴旋转矩阵 (x', y') = (x * cos a - y * sin a, x * sin a + y * cos a),但 w 随另一个轴变化。

到目前为止,这是我到达的位置,但我无法根据观看者从投影中面向的位置弄清楚如何向前导航。我可以应用逆变换来导出观众在超球面坐标中面对的归一化 4-D 矢量(称为 F),但我不知道如何使用 4x4 矩阵(OpenGL 中的最佳矩阵)朝那个方向导航).我可以考虑一个 hackish 解决方案:对于每个顶点 V,做 V' = normalize(d*F + V),其中 d 是向前移动的距离(在一些奇怪的单位中我不能完全精确)。这种方式只适用于较小的d值,d与角度变化之间没有直接关系。

因此问题是:如何在 4-D 超球面中向前移动(使用 4x4 矩阵变换)?

最佳答案

原来前段时间写了一些这方面的论文。这个 ( Interactive Visualization Methods For Four Dimensions ) 最适合您的特定问题,但引用这个的其他文档也可能对您有所帮助。在那个特定的应用程序中,我在 4D 中旋转被观察的对象,而不是观察者,但数学是等价的。

关于这个具体问题:

Thus the question is: how to move forward (using a 4x4 matrix transform) being in the surface of an 4-D hypersphere?

如果您在超球体的表面上四处移动,您并不是在翻译w。您实际上需要在球形几何体中围绕单位半径的大圆移动。这意味着,如果您可以为您的参照系构建适当的轴,您可以 spherically interpolate在你所处的位置和你要去的地方之间。

例如,可用于此类 slerp 的一种构造是使用指向正前方的单位向量(您的视线,在维基百科方程中又名 p_1),向量指向顶部你的头部 ( p_0 ) 和一个指向你右耳的向量(以形成右手坐标系)。

如果您随后以角速度而不是线性速度跟踪球体上的速度,则只需插入一个值 t (耗时)在维基百科中找到您的新角度位置。

请注意,该等式对顶点 p 中的分量数量没有限制。 .球面插值适用于任何几何形状。

编辑(回答评论中的问题):

Slerp seems not to be the case here, because I do not want to interpolate a rotation between 2 vectors over time. Instead, at each time step, I want to move every vertex into the opposite direction the viewer is moving at that moment. Thus, I am at position (0, 0, 0, 1) and I want to be at (sqrt(2)/2, sqrt(2)/2, 0, 0) next frame.

这样想:您在球体(任意维度)上的位置是一个矢量,它将您从中心移到表面。如果您以特定角速度四处移动,那么您在 p0 和时间 t0,p1 在时间 t1,等等。Slerp 是计算特定时间这些位置的便捷方法。

同样,您的视线是与位移矢量成直角的矢量。视线在时间 t0 时为 v0,在时间 t1 时为 v1,依此类推。 Slerp 再次可用于计算该向量。

How can I build the correspondent transformation matrix, so every vertex will be multiplied by the inverse of it?

使用这两个向量,orthogonalization给你第三个,你现在有了一个新的引用系。有一个single quaternion that defines the rotation从你原来的引用系到这个新的引用系。这就是您要找的。

但是,在将您的世界渲染到二维屏幕上之前,您首先需要将其从 4D 渲染为 3D。 OpenGL(不出所料)并不直接支持这一点。

要了解原因,请查看 perspective projection matrix .它假定您在 3D 空间中渲染同质点:x、y、z 在前三个分量中,w(比例因子)在第四个分量中。 w = 0 表示一个向量,而 w = 任何其他表示一个点。 w = 1 以外的任何值都是非归一化点。

因此,无法在 (0, 0, 0, 0) 的 4D 原点处渲染点。

但是,从矩阵的构造可以看出,制作 4D 到 3D 投影矩阵并不难。首先将其独立于 OpenGL 的矩阵管道应用于您的几何图形集。然后,您可以使用 OpenGL 标准矩阵将 3D 显示到屏幕上。

关于opengl - 在 OpenGL 中通过超球面导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5147526/

相关文章:

c++ - 通过 glUniform 将 GLM 的 vector 类型传递给 OpenGL

javascript - 我的立方体消失了,我不知道为什么

c - OpenGL Ubuntu 深度

opengl - 将 Material 存储为顶点属性

c++ - OpenGL 中的 Texture Splatting 是如何实现的?

c++ - OpenGL 中的矩阵乘法顺序

c++ - Mac OS X 上的 GLSL 版本 130 导致错误

c++ - cuda,OpenGL 互操作性 : cudaErrorMemoryAllocation error on cudaGraphicsGLRegisterBuffer

c++ - glRotatef 不旋转任何东西

c++ - 如何将屏幕上的鼠标坐标转换为 3D 坐标