首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据物体的方向旋转物体

如何根据物体的方向旋转物体
EN

Stack Overflow用户
提问于 2013-11-14 06:42:10
回答 1查看 5.4K关注 0票数 5

WebGL的类似问题:绕世界轴旋转物体

我需要旋转一个对象的方式,用户应该能够移动它的鼠标,就像他在拖动它。问题是,glRotatef只是旋转对象,而不考虑它的方向。对于WebGL,解决方案是使用四元数,但我猜OpenGL中没有四元数。

我现在就是这样实现轮换的:

代码语言:javascript
运行
AI代码解释
复制
// rotation 2D GLfloat C-vector, posX, posY GLfloat's
void mouse(int button, int state, int x, int y) {
    if(button== GLUT_LEFT_BUTTON) {
        if(state== GLUT_DOWN) 
        {
            posX=x;
            posY= y;
            onEvent= true;
        }
        else if(state== GLUT_UP) 
        {
            GLfloat dx= x-posX;
            GLfloat dy= y-posY;
            rotation[0]= -dy/5;
            rotation[1]= dx/5;
            onEvent= false;
            glutPostRedisplay();
        }
    }
}

然后,我处理显示函数中的旋转:

代码语言:javascript
运行
AI代码解释
复制
glPushMatrix();
glRotatef(rotation[0],1,0,0);
glRotatef(rotation[1],0,1,0);
// Draw the object
glPopMatrix();

它有点工作,但就像我说的,它应该像如果用户能够拖动对象旋转它。相反,如果对象是围绕X轴旋转90度,当用户水平拖动鼠标使其绕Y轴旋转时,它会朝相反的方向旋转。我需要一个主意,我怎么能做到呢?

编辑

我尝试使用glMultMatrixf,但是对象不能正确旋转:它不是旋转,而是缩放,这是我在鼠标函数中编辑的代码:

代码语言:javascript
运行
AI代码解释
复制
// Global variables:
// GLfloat xRotationMatrix[4][4];
// GLfloat yRotationMatrix[4][4];
else if(state== GLUT_UP && onEvent)
{
    GLfloat dx= (x-posX)/(180.0*5)*2.0*M_PI;
    GLfloat dy= (y-posY)/(180.0*5)*2.0*M_PI;
    // Computing rotations
    double cosX= cos(dx);
    double sinX= sin(dy);
    double cosY= cos(dy);
    double sinY= sin(dy);
    // x axis rotation
    xRotationMatrix[1][1]+= cosY;
    xRotationMatrix[1][2]+=-sinY;
    xRotationMatrix[2][2]+= sinY;
    xRotationMatrix[2][2]+= cosY;
    // y axis rotation
    yRotationMatrix[0][0]+= cosX;
    yRotationMatrix[0][2]+= sinX;
    yRotationMatrix[2][0]+= -sinX;
    yRotationMatrix[2][2]+= cosX;

    onEvent= false;
    glutPostRedisplay();
}

然后在显示功能中:

代码语言:javascript
运行
AI代码解释
复制
glPushMatrix();
glMultMatrixf((const GLfloat*)xRotationMatrix);
glMultMatrixf((const GLfloat*)yRotationMatrix);
glutSolidTeapot(10);
glPopMatrix();

这是非旋转茶壶:

如果我拖动鼠标水平旋转茶壶围绕y轴,而不是旋转,这是我得到的:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-15 07:43:09

首先是一点代数。设v为向量,M为当前模型视图矩阵,R为与glRotate命令关联的矩阵。然后,如果您使用glRotate,您得到的是:

M * R *

这意味着你是围绕着物体轴旋转的。你想要绕着世界的轴旋转,也就是说:

R * M *

看到区别了吗?不幸的是GL没有MatrixPreMult函数。

在现代OpenGL中,我们不再使用矩阵堆栈,实际上,在使用着色器时,我们会手动将转换矩阵传递给GL程序。大多数人所做的是编写/使用外部向量代数库(如本征)。

一种可能的(未经测试的)解决办法是,只使用旧的已废弃的GL材料,可能如下所示:

代码语言:javascript
运行
AI代码解释
复制
void rotate(float dx, float dy)
{
     //assuming that GL_MATRIX_MODE is GL_MODELVIEW
     float oldMatrix[4][4];
     glGetFloatv(GL_MODELVIEW_MATRIX,oldMatrix);
     glLoadIdentity();
     glRotatef(-dy,1,0,0);
     glRotatef(dx,0,1,0);
     glMultMatrixf(oldMatrix);
}

然后将这些代码放在mouse函数中,而不是在绘图例程中。您可以使用此技巧,方法是将视图矩阵保留在GL矩阵堆栈中,然后每次必须绘制对象时推送/弹出。我不会在大型项目中推荐这样的东西。

还请注意,如果在上面的代码中倒转两个glRotate调用的顺序,则可以得到稍微不同的结果,特别是如果dx和dy不小的话。这段代码可能会稍微好一点:

代码语言:javascript
运行
AI代码解释
复制
float angle = sqrt(dx*dx+dy*dy)*scalingFactor;
glRotate(angle,-dy,dx,0);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19980569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档