OpenTK/OpenGL局部轴旋转

OpenTK/OpenGL局部轴旋转,opengl,rotation,opentk,Opengl,Rotation,Opentk,下面是一个场景: 对象由以下内容描述: 位置 鳞片 轮换 首先,我应用OpenGL中的模型视图(摄影机),然后使用以下矩阵进行平移和旋转: private Matrix4d AnglesToMatrix(Vector3d angles) { Vector3d left = Vector3d.UnitX; Vector3d up = Vector3d.UnitY; Vector3d forward = Vector3d.UnitZ

下面是一个场景:

对象由以下内容描述:

  • 位置
  • 鳞片
  • 轮换
首先,我应用OpenGL中的模型视图(摄影机),然后使用以下矩阵进行平移和旋转:

    private Matrix4d AnglesToMatrix(Vector3d angles)
    {
        Vector3d left = Vector3d.UnitX;
        Vector3d up = Vector3d.UnitY;
        Vector3d forward = Vector3d.UnitZ;

        AnglesToAxes(angles, ref left, ref up, ref forward);

        return new Matrix4d(
            new Vector4d(left.X, up.X, forward.X, 0),
            new Vector4d(left.Y, up.Y, forward.Y, 0),
            new Vector4d(left.Z, up.Z, forward.Z, 0),
            new Vector4d(0, 0, 0, 1));
    }

    private void AnglesToAxes(Vector3d angles, ref Vector3d left, ref Vector3d up, ref Vector3d forward)
    {
        const double DEG2RAD = 0.0174532925;
        double sx, sy, sz, cx, cy, cz, theta;

        // rotation angle about X-axis (pitch)
        theta = angles.X * DEG2RAD;
        sx = Math.Sin(theta);
        cx = Math.Cos(theta);

        // rotation angle about Y-axis (yaw)
        theta = angles.Y * DEG2RAD;
        sy = Math.Sin(theta);
        cy = Math.Cos(theta);

        // rotation angle about Z-axis (roll)
        theta = angles.Z * DEG2RAD;
        sz = Math.Sin(theta);
        cz = Math.Cos(theta);

        // determine left axis
        left.X = cy * cz;
        left.Y = sx * sy * cz + cx * sz;
        left.Z = -cx * sy * cz + sx * sz;

        // determine up axis
        up.X = -cy * sz;
        up.Y = -sx * sy * sz + cx * cz;
        up.Z = cx * sy * sz + sx * cz;

        // determine forward axis
        forward.X = sy;
        forward.Y = -sx * cy;
        forward.Z = cx * cy;
    }
最后,我应用了scale。除了基于全局轴的旋转外,所有这些看起来都很棒

如何使用局部轴旋转对象

使问题精确。当我在Y轴上将对象旋转45度时,X轴和Z轴随之旋转,然后使用新轴应用另一个旋转

为了避免以过失的形式受到惩罚。。。我阅读了所有与三维空间旋转相关的主题,没有一个给了我答案。上述代码是应用各种尝试的结果,但其产生的结果与以下相同:

        GL.Rotate(Rotation.X, Vector3d.UnitX);
        GL.Rotate(Rotation.Y, Vector3d.UnitY);
        GL.Rotate(Rotation.Z, Vector3d.UnitZ);
编辑: 事实证明,我们的设计师对三维物体的旋转有着不好的期望,但问题仍然存在。至于使用的语言,我们在C语言中写这个,但是如果你给我一个C或C++的解决方案,我会处理它:d

我们目前使用(可配置订单):

但这会绕世界轴旋转对象。我们想要的是像这样使用局部对象轴,假设我们有X-Y-Z轴旋转:

GL.Rotate(Rotation.X, Vector3d.UnitX);
GL.Rotate(Rotation.Y, newYaxis);
GL.Rotate(Rotation.Z, newZaxis);
或者假设我们有Y-X-Z轴旋转

GL.Rotate(Rotation.Y, Vector3d.UnitY);
GL.Rotate(Rotation.X, newXaxis);
GL.Rotate(Rotation.Z, newZaxis);

最有效的方法是预先计算旋转矩阵,但我仍然想知道旋转后如何确定新的轴。(我不得不重温一下三角学这本书)。如果有人能很快计算出旋转矩阵,我将不胜感激。现在,我将尝试在每次过程中使用三角计算。

我对opentk不是很在行,但对于C风格的opengl,这是乘法前和乘法后的区别。预乘发生在世界坐标空间,后乘发生在局部坐标空间。见第9.070节


如果你能得到一个实际矩阵的句柄来执行矩阵乘法,这应该是可行的。

你能确切地说出你在这里设想的情况吗

我认为你的要求毫无意义。对于任何旋转,可以在另一个操作(全局轴)之前应用它,也可以在另一个操作(局部轴)之后应用它。因此,如果要应用三个旋转,一个轴旋转必须是第一个,另一个轴旋转必须是第二个,另一个轴必须是第三个

您的意思是希望应用三个旋转,但希望每个旋转在其他两个旋转之前发生。他们不可能都是第一


如果你对你想要实现的旋转进行更多的描述(首选图像),也许我们可以澄清这个误解,但你目前提出的问题在物理现实中对我来说没有意义。

旋转必须以特定的顺序发生,但在绕一个轴旋转之后,我必须为下一个旋转计算新的轴。
GL.Rotate(Rotation.Y, Vector3d.UnitY);
GL.Rotate(Rotation.X, newXaxis);
GL.Rotate(Rotation.Z, newZaxis);