2013-05-18 31 views
0

我遇到了绘制模型和使用鼠标旋转的问题, 我很确定数学中存在问题但不确定。 该对象只是以一种奇怪的方式旋转。 我希望对象从当前点开始旋转每次点击,并且不会因为 而重置,因此矢量现在会更改并且计算会重新开始。opengl - 围绕使用向量的球体旋转而不使用glulookat

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是任何计算错了?似乎无法找到问题... 谢谢

回答

1

为什么这么复杂?您可以更改视图矩阵,也可以更改焦点对象的模型矩阵。如果您选择更改模型矩阵并且您的对象以世界坐标系的(0,0,0)为中心,那么计算围绕球体错觉的旋转是微不足道的 - 您只需旋转到相反的方向。如果你想改变视图矩阵(当你改变相机的位置时它实际上完成了),你必须逼近所选球体上的表面点。因此,您可以引入两个指定两个角度的参数。每次点击移动鼠标,您都会更新参数并计算球体上的新位置。 [http://en.wikipedia.org/wiki/Sphere]中有一些有用的等式。

1

不知道使用代码的库(或多个库)很难阅读。看起来您正在将相机设置在(0,0,250)处,朝着原点方向看,然后围绕原点旋转两个矢量model->getCurrRotate()model->getBeginRotate()之间的角度。

问题似乎是,在“鼠标向下”事件中,您明确地将BeginRotate设置为鼠标下的球体上的点,然后在“鼠标移动”事件中将CurrRotate设置为鼠标下面的点,你点击别的地方,你会失去以前的旋转状态,因为BeginRotate和CurrRotate只是被覆盖。

在任意不同的轴周围组合多次旋转并不是一项简单的任务。正确的做法是使用四元数。您可能会发现this primer on quaternions and other 3D math concepts有用。

您可能还需要一个更强大的算法来将屏幕坐标转换为球体上的模型坐标。你使用的是假设球体在屏幕上出现半径为70像素,并且投影矩阵是正交的。