Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL rubiks立方体-使用鼠标进行面旋转_C++_Opengl_Rubiks Cube - Fatal编程技术网

C++ OpenGL rubiks立方体-使用鼠标进行面旋转

C++ OpenGL rubiks立方体-使用鼠标进行面旋转,c++,opengl,rubiks-cube,C++,Opengl,Rubiks Cube,我正在做我的第一个真正的OpenGL项目。它是一个3x3x3的Rubiks立方体。这里有一个链接,指向一个简单的截图 在按住鼠标右键的同时拖动鼠标,即可旋转立方体。这是使用NeHe教程()中的弧球示例实现的 我有一个类singleCubes,它通过6个实际的四边形表示一个立方体,存储在一个显示列表中,可以在它的draw方法中使用。 ComplexCube类有一个3x3x3单立方体的数组,在与完整的rubiks立方体交互时用作接口 现在我想根据鼠标左键按下的鼠标标记旋转每个特定的面。我使用pick

我正在做我的第一个真正的OpenGL项目。它是一个3x3x3的Rubiks立方体。这里有一个链接,指向一个简单的截图

在按住鼠标右键的同时拖动鼠标,即可旋转立方体。这是使用NeHe教程()中的弧球示例实现的

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

现在我想根据鼠标左键按下的鼠标标记旋转每个特定的面。我使用picking来获取用户单击的单个多维数据集对应侧的id。这也行得通。因此,我单击面上一个立方体的一侧,并根据拖动的方向设置受影响立方体的旋转和偏移因子。(我还想实现你实际看到的面是旋转的,而不是仅仅改变颜色)

现在我的问题是,当我用鼠标右键拖动rubiks立方体在任何方向上旋转时,它就会颠倒过来。因此,当我点击一个侧面并想将面向右旋转时,它会朝着错误的方向移动,因为我无法跟踪立方体是否倒置或其他情况。由于使用了弧球旋转,我没有一个x或y旋转角度,我可以用它来确定

问题1:在使用上面链接的arcball示例时,如果立方体倒置、倾斜等,我如何跟踪或稍后获取信息,以便转换鼠标拖动信息(旋转一面时)

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

安装:C++与微软Visual Studio 2008,GLew,FeleGuLuts/P>< P>就像我们大多数人一样,你会遇到著名的问题,称为万向锁。 见:


这个问题有很好的文档记录,所以我没有太多的理由在这里详细讨论。我相信您会找到大量关于它的信息。

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

基本上,一旦你得到你的“力”向量,你就把它投射到三个轴上(所以投射到(1,0,0),(0,1,0),(0,0,1))。然后选择震级最大的一个。然后,您必须将此方向转换为旋转轴,如下图所示(抱歉,绘制技巧不好):

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

编辑以更详细地回答问题

因此,继续我的解释,我将给出一个例子,说明这将如何帮助您。让我们首先假设您的屏幕为800x800像素,并且您的rubiks立方体始终居中。现在,让我们假设,根据您在评论中的绘图,我们位于左侧的案例中

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

现在我们得到差向量:p2-p1=v=(0.3,-0.05,0)。我之所以说“投射到三个轴上”,是为了提取你的主要运动(在本例中,x轴为0.3)(因为rubiks立方体不能沿对角线旋转)。要进行“投影”,您只需分别获取x、y、z轴,并从中创建矢量,从而得到:

v1 = (0.3, 0, 0)
v2 = (0, -0.05, 0)
v3 = (0, 0, 0)
现在取震级,去掉最小的向量,剩下向量v1=(0.3,0,0)。这是你在世界空间中的运动矢量。现在取该向量与所选面的法向量(在本例中为(0,0,1))的叉积。这将为您提供一个向下(0,1,0)的向量(归一化后)(在这一步中,您可能还需要仅提取最大分量(0.02,1.2,0.8)->(0,1,0),否则如果您的相机没有直接指向主轴,您将获得奇怪的旋转)。现在,您可以使用该向量作为旋转轴,并使用0.3作为旋转量(如果它以与预期方向相反的方向旋转,只需放置一个-)

如果你的立方体是颠倒的,这有什么帮助?假设我们以同样的方式点击屏幕。我们现在得到:

p1 : (600, 600) -> (-1, 0.5, 0)
p2 : (630, 605) -> (-1.3, 0.505, 0)
看到世界坐标的差异了吗?他们倒了!所以当你取差向量p2-p1=v=(-0.3,0.05,0)。提取最大分量向量得到(-0.3,0,0)。再次做叉积可以得到旋转轴,但是现在旋转方向是相反的,这就是你想要的


与面法线交叉积的另一个原因是,如果要选择顶部的面(在我们的图形中),则它将沿x或z轴(向左或进入屏幕)提供一个旋转轴,这是您想要的顶部面的旋转轴。

OpenGL不是场景图,您可以将“对象”放入其中。它只是画东西。记账是你的工作。是的,你是对的。也许是我的错,我没有完全理解NeHe的arcball示例,因此无法保存立方体的旋转状态。我不明白这怎么能以任何方式回答他的问题。即使万向节锁对他来说是个问题(鉴于他的陈述,这不是预先确定的),那么这可能是一个更好的评论,因为目前这肯定不是他的问题
p1 : (600, 600) -> (-1, 0.5, 0)
p2 : (630, 605) -> (-1.3, 0.505, 0)