基于MFC,用OpenGL把物体绕世界坐标系的单根轴连续旋转问题

章鱼小八 2018-12-20 07:03:06
要求:选择旋转的坐标轴,鼠标拖动模型绕该坐标轴旋转;要求是多次操作,模型可以连续绕不动的世界坐标系的坐标轴旋转,切换坐标轴,模型能够接着上次的位置继续旋转。

我先画出了绘图坐标系和世界坐标系。
我发现我运行程序后,选择旋转轴的顺序不同会有不同的结果,比如先选绕Z轴转(此时分辨不出,因为绘图坐标系与世界坐标系重合),然后选择绕X,Y轴转都是按照世界坐标系,但是再选绕Z轴转,却是绕绘图坐标系的Z轴。
以上是一些代码的顺序,先画世界坐标系,再调用旋转函数,在画绘图坐标系和模型。



以上是绕不同轴旋转的函数,我发现哪一个放在最下面,则它一定是按照绘图坐标系转而不是世界坐标系,并且先执行它,则其他两个正确。




以下是主要的代码,环境搭建的我都删了,以下是实现功能的,大佬帮我看看 问题出在哪儿?能不能用简单一点的方法达到我的要求?我也是初学者~

CMy001View::CMy001View()
{
// TODO: add construction code here
xMax= 100;
xMin=-100;
yMax= 100;
yMin=-100;
zMax=500;
zMin=-50;


m_bInMouseRotate=0;
m_LeftDownPos=(0,0);
m_xRotate=0;
m_yRotate=0;
m_zRotate=0;
m_xMouseRotation=0;
m_yMouseRotation=0;
m_zMouseRotation=0;

}


void CMy001View::OnDraw(CDC* pDC)
{
CMy001Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
HDC hdc;
HGLRC rc;
glDrawBuffer(GL_BACK);
//GetCurrent(hdc, rc);//Store current rendering and device contexts
//MakeActive();//Make view's rendering context current
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
SetupOrtho();
::glPushMatrix();


gluLookAt(200.0,200.0,200.0,0.0,0.0,0.0, 0.0,0.0,1.0);//定义观察坐标系


glBegin(GL_LINES);//世界坐标系

glColor3f(0.0,0.0,1.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 60.0, 0.0, 0.0);

glColor3f(0.0,1.0,0.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 60.0, 0.0);

glColor3f(1.0,0.0,0.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 0.0, 60.0);

glEnd();


DoMouseRotate();//坐标旋转变换


glBegin(GL_LINES);//模型坐标系

glColor3f(0.0,0.0,1.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 60.0, 0.0, 0.0);

glColor3f(0.0,1.0,0.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 60.0, 0.0);

glColor3f(1.0,0.0,0.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 0.0, 60.0);

glEnd();

RenderScene(); //画一个正方体


//在这里添加绘图的函数
::glPopMatrix();

// Tell OpenGL to flush its pipeline
::glFinish();

// Now Swap the buffers
if ( FALSE == ::SwapBuffers(m_pDC->GetSafeHdc()))
return;
}

/////////////////////////////////////////////////////////////////////////////
// CMy001View printing


void CMy001View::DoMouseRotate()
{

glRotatef(m_xMouseRotation, 1.0, 0.0, 0.0);
glRotatef(m_yMouseRotation, 0.0, 1.0, 0.0);
glRotatef(m_zMouseRotation, 0.0, 0.0, 1.0);

}



void CMy001View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_bool==1)
{
trackball_MouseDown(point);
}


CView::OnLButtonDown(nFlags, point);
}
void CMy001View::trackball_MouseDown(CPoint point)
{
m_LeftDownPos = point;//将该值赋给变量m_LeftDownPos
SetCapture();
::SetCursor(LoadCursor(NULL, IDC_SIZEALL));
m_bInMouseRotate=TRUE;//////////////////


}

void CMy001View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

if(m_bInMouseRotate==true)
{
trackball_MouseMove(point);//获得鼠标点的坐标,并调用trackball_MouseMove()
}



CView::OnMouseMove(nFlags, point);
}

void CMy001View::trackball_MouseMove(CPoint point)
{
ASSERT(GetCapture()==this);
::SetCursor(LoadCursor(NULL, IDC_SIZEALL));
if(m_bInMouseRotate==true)
{
if(m_xRotate==1)
{
m_xMouseRotation -= (float)(m_LeftDownPos.x - point.x)/3.0f;
}
if(m_yRotate==1)
{
m_yMouseRotation -= (float)(m_LeftDownPos.x - point.x)/3.0f;
}
if(m_zRotate==1)
{
m_zMouseRotation -= (float)(m_LeftDownPos.x - point.x)/3.0f;
}


m_LeftDownPos = point;
}

InvalidateRect(NULL,FALSE);
}

void CMy001View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_bInMouseRotate==true)
{
trackball_MouseUp(point);//获得鼠标点的坐标,并调用trackball_MouseUp()

}

CView::OnLButtonUp(nFlags, point);
}
void CMy001View::trackball_MouseUp(CPoint point)
{
//m_LeftDownPos = CPoint(0,0); // forget where we clicked
//m_LeftUpPos=point;
ReleaseCapture();
m_bInMouseRotate=FALSE;

}

void CMy001View::OnxRotate()
{
// TODO: Add your command handler code here
m_xRotate=1;
m_yRotate=0;
m_zRotate=0;
m_bool=1;
}

void CMy001View::OnyRotate()
{
// TODO: Add your command handler code here
m_yRotate=1;
m_xRotate=0;
m_zRotate=0;
m_bool=1;
}

void CMy001View::OnzRotate()
{
// TODO: Add your command handler code here
m_zRotate=1;
m_xRotate=0;
m_yRotate=0;
m_bool=1;
}
void CMy001View::RenderScene()
{


cube();
}

void CMy001View::cube()
{


glBegin(GL_LINES);//画一个正方体

glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 30.0, 0.0, 0.0);
glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 30.0, 0.0);
glVertex3f( 30.0, 30.0, 0.0);
glVertex3f( 30.0, 0.0, 0.0);
glVertex3f( 30.0, 30.0, 0.0);
glVertex3f( 0.0, 30.0, 0.0);

glVertex3f( 0.0, 0.0, 0.0);
glVertex3f( 0.0, 0.0, 30.0);
glVertex3f( 30.0, 0.0, 0.0);
glVertex3f( 30.0, 0.0, 30.0);
glVertex3f( 0.0, 30.0, 0.0);
glVertex3f( 0.0, 30.0, 30.0);
glVertex3f( 30.0, 30.0, 0.0);
glVertex3f( 30.0, 30.0, 30.0);

glVertex3f( 0.0, 0.0, 30.0);
glVertex3f( 30.0, 0.0, 30.0);
glVertex3f( 0.0, 0.0, 30.0);
glVertex3f( 0.0, 30.0, 30.0);
glVertex3f( 30.0, 30.0, 30.0);
glVertex3f( 0.0, 30.0, 30.0);
glVertex3f( 30.0, 30.0, 30.0);
glVertex3f( 30.0, 0.0, 30.0);

glEnd();
}





...全文
590 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_43980222 2019-01-02
  • 打赏
  • 举报
回复
兄弟搞清楚了吗? 我也遇到了这个问题。
章鱼小八 2018-12-25
  • 打赏
  • 举报
回复
有人帮忙看看嘛
章鱼小八 2018-12-21
  • 打赏
  • 举报
回复
我自己发现了一点,三个旋转是有顺序的,最下面的旋转语句最先执行,所以它一定是按绘图坐标系转。但是不知道如何修改~

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧