我正在开发我的第一个真正的OpenGL项目。这是一个3x3x3 Rubiks立方体。这是到目前为止(my rubiks cube)
的简单屏幕截图的链接旋转立方体是在按住鼠标右键的同时拖动鼠标完成的。这可以使用NeHe Tutorials(NeHe Arcball)
中的弧形示例我有类singleCubes,它通过6个实际四边形表示一个立方体,存储在可以在其绘制方法中使用的显示列表中。 ComplexCube类具有3x3x3单个立方体的数组,在与完整的rubiks立方体交互时用作接口。
现在我想根据mousedragging用鼠标左键旋转每个特定的脸部。我使用pick来获取用户点击的单个多维数据集的相应边的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 ++与Microsoft Visual Studio 2008,GLEW,freeglut
答案 0 :(得分:4)
您可以使用gluUnProject将鼠标坐标转换为3d空间并获取矢量(两点之间的差异)。然后可以使用该向量将“力”施加到所选择的面部。由于gluUnProject使用投影矩阵,它会自动处理相机的方向。
基本上,一旦获得“力”向量,就将其投影到三个轴上(所以在(1,0,0),(0,1,0),(0,0,1)上)。然后选择幅度最大的那个。然后你必须将这个方向转换为旋转轴,如下图所示(对不起油漆技巧感到抱歉):
所以我们所拥有的是黑色的“力”矢量,所选的红宝石面朝灰色。要获得旋转轴,只需将十字产品的“力”向量与所选面的法线相乘。这给出了红色箭头。从那以后,您应该能够以正确的方向旋转立方体。
编辑以更详细地回答问题
继续我的解释,我将举例说明这将如何帮助你。我们首先假设您的屏幕是800x800像素,并且您的rubiks立方体始终居中。现在让我们假设,根据评论中的图纸,我们在左边的情况下。
我们拖动鼠标并获得两个位置,使用gluUnProject将其转换为世界坐标(选择数字以显示我的观点,而不是通过任何计算):
p1 : (600, 600) -> (1, -0.5, 0)
p2 : (630, 605) -> (1.3, -0.505, 0)
现在我们得到差分向量: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,3.05,0)时。提取最大分量向量给出(-0.3,0,0)。再次执行十字产品会为您提供旋转轴,但现在旋转方向相反,这就是您想要的。
与正常面交叉积的另一个原因是,如果你要选择顶部的面(在我们的图纸中),那么它将沿x或z轴给出一个旋转轴(对于离开,或进入屏幕)这是你想要的顶面。
答案 1 :(得分:0)
像我们大多数人一样,你会遇到一个名为Gimbal Lock的着名问题。
请参阅:http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=208925
这个问题记录得很清楚,所以我没有太多意义在这里详细介绍。我相信你会找到关于它的大量信息。