Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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
OpenGL中的旋转保持_Opengl - Fatal编程技术网

OpenGL中的旋转保持

OpenGL中的旋转保持,opengl,Opengl,我正在画一个对象,比如说,OpenGL中的一个立方体,用户可以通过在窗口上单击/拖动鼠标来旋转它。立方体的绘制方式如下: void CubeDrawingArea::redraw() { Glib::RefPtr gl_drawable = get_gl_drawable(); gl_drawable->gl_begin(get_gl_context()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

我正在画一个对象,比如说,OpenGL中的一个立方体,用户可以通过在窗口上单击/拖动鼠标来旋转它。立方体的绘制方式如下:


void CubeDrawingArea::redraw()
{ 
    Glib::RefPtr gl_drawable = get_gl_drawable();

    gl_drawable->gl_begin(get_gl_context());

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    {
        glRotated(m_angle, m_rotAxis.x, m_rotAxis.y, m_rotAxis.z);
        glCallList(m_cubeID);
    }
    glPopMatrix();

    gl_drawable->swap_buffers();

    gl_drawable->gl_end();
}
并使用此功能进行旋转:

}


有一些GTK+的东西在那里,但它应该是非常明显的,它的目的。get_trackball_point函数将窗口坐标X Y投影到虚拟轨迹球的半球上,虚拟轨迹球用作旋转对象的参考点。无论如何,这或多或少是可行的,但在我完成旋转后,我再次旋转,立方体会恢复到原始位置,很明显,因为下次旋转时m_角度将重置为接近0。有没有办法避免这种情况并保持旋转?

是的,我也遇到了这个问题

您需要做的是保留一个累积当前旋转状态的旋转矩阵,并将其与来自当前拖动操作的旋转矩阵一起使用

假设你有两个矩阵,lastRotMx和currotmx。如果你愿意的话,让他们成为Cubedrawingara的成员

您没有向我们展示这一点,但我假设只要鼠标按钮向下拖动,m_lastTrackPoint就会初始化。发生这种情况时,将currotmx复制到lastRotMx中

然后在on_motion_notify_事件中,在计算m_旋转轴和m_角度后,基于m_旋转轴和m_角度创建新的旋转矩阵draggingRotMx;然后将lastRotMx与draggingRotMx相乘,并将结果放入currRotMx

最后,在重画中,而不是

按currotmx旋转

更新:或者代替所有这些。。。我还没有对此进行测试,但我认为它会起作用:

使cur_pos成为类成员,使其保持不变,但它初始化为零,就像m_lastTrackPoint一样。 然后,每当启动新的拖动运动时,在初始化m_lastTrackPoint之前,让_3vdpos=cur_pos-m_lastTrackPoint伪代码。 最后,当您基于鼠标事件坐标初始化m_lastTrackPoint时,从中减去dpo

这样,您的cur_pos将已经从m_lastTrackPoint偏移了一个量,该量基于过去电弧球拖动的偏移累积

可能错误也会累积,但它应该是足够渐进的,以便不被察觉。但我想测试一下以确定。。。组合旋转非常复杂,我不相信它们,除非看到它们

另外,你的用户名会让你失去动力。建议再选一个


p.p.S.对于那些稍后来搜索此问题答案的人,要搜索的关键字是。一篇权威性的文章是Ken Shoemake在中的章节。看看这个。

我真的不明白你的第一个建议是怎么起作用的。旋转角度仍然是当前拖动偏移的函数,因此在这种情况下,我将使用不同的方法旋转立方体,但之后,我将再次旋转,角度将接近于零,我将返回到1。事实上,在百灵鸟上,我确实实现了你的建议,并得到了相同的结果。至于你的第二个建议,我尝试了一些变化,我作为一个成员保持当前轨迹球的位置,在重画之前设置m_lastTrackPoint=当前轨迹点,并在重画函数中删除对glPushMatrix和glPopMatrix的调用。这使得它不会在我下一次旋转时被重置,但现在在下一次旋转时,它在我假设的变换坐标系中旋转,所以我得到了奇怪的结果…@Bit:re:1st注释:重画中的旋转角度不仅仅是当前拖动偏移的函数,而是累积旋转和当前拖动偏移的函数。开始拖动时,是否将currRotMx保存到lastRotMx中,并在拖动时将currRotMx设置为draggingRotMx和lastRotMx的乘积?@Bit:re:2nd comment:是的,我想我也尝试了你的变体,但没有成功。正如你所说,它在变换后的坐标系中旋转,所以它不起作用。正如您所知,旋转必须按正确的顺序组合。@Bit:我的示例代码位于;查看它加载的js文件。arcball旋转与早期版本的WebGL一起累积工作;现在可能不行。但是代码仍然应该更精确地传达方法。 bool CubeDrawingArea::on_motion_notify_event(GdkEventMotion* motion) { if (!m_leftButtonDown) return true;

_3V cur_pos;
get_trackball_point((int) motion->x, (int) motion->y, cur_pos);

const double dx = cur_pos.x - m_lastTrackPoint.x;
const double dy = cur_pos.y - m_lastTrackPoint.y;
const double dz = cur_pos.z - m_lastTrackPoint.z;

if (dx || dy || dz)
{
    // Update angle, axis of rotation, and redraw

    m_angle = 90.0 * sqrt((dx * dx) + (dy * dy) + (dz * dz));

    // Axis of rotation comes from cross product of last / cur vectors
    m_rotAxis.x = (m_lastTrackPoint.y * cur_pos.z) - (m_lastTrackPoint.z * cur_pos.y);
    m_rotAxis.y = (m_lastTrackPoint.z * cur_pos.x) - (m_lastTrackPoint.x * cur_pos.z);
    m_rotAxis.z = (m_lastTrackPoint.x * cur_pos.y) - (m_lastTrackPoint.y * cur_pos.x);

    redraw();
}

return true;
   glRotated(m_angle, m_rotAxis.x, m_rotAxis.y, m_rotAxis.z);