gpt4 book ai didi

c++ - OpenGL rubiks cube - 用鼠标进行面部旋转

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:28 26 4
gpt4 key购买 nike

我正在从事我的第一个真正的 OpenGL 项目。这是一个 3x3x3 的魔方。这是我到目前为止所拥有的简单屏幕截图的链接(my rubiks cube)

旋转立方体是通过在按住鼠标右键的同时拖动鼠标来完成的。这使用 NeHe 教程中的轨迹球示例 ( NeHe Arcball )

我有一个类 singleCubes,它通过 6 个实际的四边形表示一个立方体,存储在一个显示列表中,可以在它的绘制方法中使用。ComplexCube 类有一个 3x3x3 singleCubes 数组,在与完整的 rubiks 立方体交互时用作接口(interface)。

现在我想根据按下鼠标左键的鼠标拖动来旋转每个特定的脸。我使用 picking 来获取用户点击的单个立方体对应边的 id。这也有效。所以我点击一个立方体的一侧,根据拖动的方向,我设置了受影响的立方体的旋转和偏移因子。 (我还想实现你实际上看到的是面部旋转而不是仅仅改变颜色)

现在我的问题是,当我用鼠标右键拖动向任何方向旋转 rubiks 立方体时,它会变得颠倒,例如。因此,当我单击一侧并想将面向右旋转时,它的方向是错误的,因为如果立方体是倒置的或其他什么,我无法跟踪。由于使用了轨迹球旋转,我没有 x 或 y 旋转角度可以用来确定这一点。

问题 1:如果立方体倒置、倾斜等,我如何跟踪或稍后获取信息,以便在使用上面链接的弧球示例?

// In render function
glPushMatrix();
{
glMultMatrixf(Transform.M); // Rotation applied by arcball object
complCube.draw(); // Draw all the cubes using display lists
}
glPopMatrix();

设置:C++ 和 Microsoft Visual Studio 2008、GLEW、freeglut

最佳答案

您可以使用 gluUnProject 将鼠标坐标转换为 3d 空间并获得 vector (两点之间的差异)。然后可以使用该 vector 对选定的面施加“力”。由于 gluUnProject 使用投影矩阵,它会自动处理相机的方向。

基本上,一旦获得“力” vector ,就可以将其投影到三个轴上(因此投影到 (1,0,0)、(0,1,0)、(0,0,1))。然后选择幅度最大的那个。然后你必须把这个方向转换成一个旋转轴,如下图(画画不好请见谅):

Example of the vectors used in the explanation

所以我们得到的是黑色的“力” vector 和灰色的选定魔方面。要获得旋转轴,只需将“力” vector 与所选面的法线相乘即可。这给出了红色箭头。由此,您应该能够以正确的方向旋转立方体。

编辑以更详细地回答问题

继续我的解释,我将举例说明这将如何帮助您。让我们首先假设您的屏幕是 800x800 像素并且您的魔方始终居中。现在我们还假设,根据您在评论中的绘图,我们在左侧的情况下。

我们拖动鼠标得到两个位置,使用 gluUnProject 将其转换为世界坐标(选择数字是为了表明我的观点,而不是通过任何计算):

p1 : (600, 600) -> (1, -0.5, 0)
p2 : (630, 605) -> (1.3, -0.505, 0)

现在我们得到差值 vector :p2 - p1 = v = (0.3, -0.05, 0)。我之所以说“转换到三个轴上”是为了提取主要运动(在本例中是 x 轴上的 0.3)(因为魔方不能沿对角线旋转)。要进行“投影”,您只需单独获取 x、y、z 轴并从中创建 vector ,这样您就可以得到:

v1 = (0.3, 0, 0)
v2 = (0, -0.05, 0)
v3 = (0, 0, 0)

现在获取幅度并丢弃最小的 vector ,所以我们剩下 vector v1 = (0.3, 0, 0)。这是您在世界空间中的运动 vector 。现在您将该 vector 与所选面的法 vector (在本例中为 (0, 0, 1))相乘。这为您提供了一个向下指向 (0, 1, 0) 的 vector (归一化后)(在此步骤中,您可能还必须仅提取最大分量 (0.02, 1.2, 0.8) -> (0, 1, 0)否则如果你的相机没有直接指向主轴,你会得到奇怪的旋转)。您现在可以使用该 vector 作为旋转轴并使用 0.3 作为旋转量(如果它以与预期相反的方向旋转,只需输入 -)。

现在,如果您的立方体倒置,这有何帮助?假设我们以同样的方式点击屏幕。我们现在得到:

p1 : (600, 600) -> (-1, 0.5, 0)
p2 : (630, 605) -> (-1.3, 0.505, 0)

看到世界坐标的不同了吗?他们颠倒了!所以当你取差分 vector p2 - p1 = v = (-0.3, 0.05, 0)。提取最大分量 vector 给出 (-0.3, 0, 0)。再次进行叉积得到旋转轴,但现在旋转方向相反,这正是您想要的。

与面的法线进行叉积的另一个原因是,如果您要选择顶部的面(在我们的绘图中),那么它会给出沿 x 或 z 轴的旋转轴(到左,或进入屏幕)这是你想要的顶面。

关于c++ - OpenGL rubiks cube - 用鼠标进行面部旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7915201/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com