gpt4 book ai didi

c++ - 如何根据物体的方向旋转物体

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

WebGL 的类似问题:Rotate object around world axis .

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

这就是我现在实现轮换的方式:

// 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();
}
}
}

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

glPushMatrix();
glRotatef(rotation[0],1,0,0);
glRotatef(rotation[1],0,1,0);
// Draw the object
glPopMatrix();

它有点管用,但就像我说的那样,如果用户能够拖动对象来旋转它,它应该会喜欢。相反,如果对象绕 X 轴旋转 90 度,当用户水平拖动鼠标使其绕 Y 轴旋转时,它会沿相反方向旋转。我需要一个想法,我该怎么做?

编辑

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

// 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();
}

然后在显示函数中:

glPushMatrix();
glMultMatrixf((const GLfloat*)xRotationMatrix);
glMultMatrixf((const GLfloat*)yRotationMatrix);
glutSolidTeapot(10);
glPopMatrix();

这是不旋转的茶壶:

enter image description here

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

enter image description here

最佳答案

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

M * R * v

这意味着您正在围绕对象轴旋转。您想围绕世界轴旋转,即:

R * M * v

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

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

一个可能的(未经测试的)解决方法是只使用旧的已弃用的 GL 东西可能是这样的:

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 函数中,而不是draw 例程中。您可以通过将 View 矩阵保留在 GL 矩阵堆栈中来使用此技巧,然后在每次必须绘制对象时插入/弹出。我不会在大型项目中推荐类似的东西。


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

float angle = sqrt(dx*dx+dy*dy)*scalingFactor;
glRotate(angle,-dy,dx,0);

关于c++ - 如何根据物体的方向旋转物体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19980569/

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