我在绘制模型并使用鼠标旋转模型时遇到问题, 我很确定数学有问题但不确定。 物体只是以一种奇怪的方式旋转。 我希望对象从当前位置开始旋转每次单击而不是因为重置而重置 矢量现在已经改变,计算又重新开始。
void DrawHandler::drawModel(Model * model){
unsigned int l_index;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Modeling transformation
glLoadIdentity();
Point tempCross;
crossProduct(tempCross,model->getBeginRotate(),model->getCurrRotate());
float tempInner= innerProduct(model->getBeginRotate(),model->getCurrRotate());
float tempNormA =normProduct(model->getBeginRotate());
float tempNormB=normProduct(model->getCurrRotate());
glTranslatef(0.0,0.0,-250.0);
glRotatef(acos (tempInner/(tempNormA*tempNormB)) * 180.0 / M_PI,tempCross.getX(),tempCross.getY(),tempCross.getZ());
glColor3d(1,1,1);
glBegin(GL_TRIANGLES);
for (l_index=0;l_index < model->getTrianglesDequeSize() ;l_index++)
{
Triangle t = model->getTriangleByPosition(l_index);
Vertex a1 = model->getVertexByPosition(t.getA());
Vertex a2 = model->getVertexByPosition(t.getB());
Vertex a3 = model->getVertexByPosition(t.getC());
glVertex3f( a1.getX(),a1.getY(),a1.getZ());
glVertex3f( a2.getX(),a2.getY(),a2.getZ());
glVertex3f( a3.getX(),a3.getY(),a3.getZ());
}
glEnd();
}
这是保存旋转公式
的起始矢量的鼠标功能 void Controller::mouse(int btn, int state, int x, int y)
{
x=x-WINSIZEX/2;
y=y-WINSIZEY/2;
if (btn==GLUT_LEFT_BUTTON){
switch(state){
case(GLUT_DOWN):
if(!_rotating){
_model->setBeginRotate(Point(float(x),float(y),
(-float(x)*x - y*y + SPHERERADIUS*SPHERERADIUS < 0)? 0:float(sqrt(-float(x)*x - y*y + SPHERERADIUS*SPHERERADIUS))));
_rotating=true;
}
break;
case(GLUT_UP):
_rotating=false;
break;
}
}
}
最后是保存当前向量的以下函数。 (开始向量是单击鼠标的位置 并且curr向量是当前鼠标位置的位置)
void Controller::getMousePosition(int x,int y){
x=x-WINSIZEX/2;
y=y-WINSIZEY/2;
if(_rotating){
_model->setCurrRotate(Point(float(x),float(y),
(-float(x)*x - y*y + SPHERERADIUS*SPHERERADIUS < 0)? 0:float(sqrt(-float(x)*x - y*y + SPHERERADIUS*SPHERERADIUS))));
}
}
其中sphereradius是70度的球半径O_O
有任何计算错误吗?似乎无法找到问题...... 感谢
答案 0 :(得分:1)
为什么这么复杂?您可以更改视图矩阵,也可以更改焦点对象的模型矩阵。如果您选择更改模型矩阵并且您的对象位于世界坐标系的(0,0,0)中心,则计算围绕球体旋转的旋转是微不足道的 - 您只需旋转到相反的方向。如果要更改视图矩阵(实际上在更改摄像机位置时已完成),则必须近似所选球体上的曲面点。因此,您可以引入两个指定两个角度的参数。每次单击移动鼠标时,都会更新参数并计算球体上的新位置。 [http://en.wikipedia.org/wiki/Sphere]中有一些有用的公式。
答案 1 :(得分:1)
在不知道您正在使用哪些库(或库)的情况下,您的代码难以阅读。您似乎正在设置相机(0,0,-250),朝向原点,然后围绕原点旋转两个矢量model->getCurrRotate()
和model->getBeginRotate()
之间的角度。
问题似乎是在“鼠标按下”事件中你明确地将BeginRotate设置为鼠标下球体上的点,然后在“鼠标移动”事件中将CurrRotate设置为鼠标下方的点,所以每次你单击其他位置,您将失去先前的旋转状态,因为BeginRotate和CurrRotate只是被覆盖。
在任意不同的轴周围组合多个旋转不是一项简单的任务。正确的方法是使用四元数。您可能会发现this primer on quaternions and other 3D math concepts有用。
您可能还需要一种更强大的算法,用于将屏幕坐标转换为球体上的模型坐标。您正在使用的是假设球体在屏幕上显示半径为70像素,并且投影矩阵是正交的。